Static Site Redirects With Astro (or Any Static Site Builder)

Lloyd Atkinson

Background

While developing my site and setting up the newsletter I decided I’d like to be able to send a link in the welcome e-mail to the most recent article or project I posted. Updating the link in the welcome e-mail template every time a new article is published would be bad as it can be automated to eliminate another manual process.

Now, as I’m using a static site generator to build my site, I don’t have an API that would traditionally be used to take the user to the most recent post.

This is a common enough scenario. It can still easily be achieved with a static site, even at build time. It can even be done without any client side Javascript - a benefit for static sites!

How I redirect visitors to my latest article

I’m using Astro to build my site so the code and examples are for that. However, the concepts presented here can be applied to other frameworks and tools as well.

Below is the Astro component I’m using to build the redirection feature. As per the documentation static routes are built based on the file system hierarchy.

Astro uses file-based routing to generate your build URLs based on the file layout of your project src/pages directory. When a file is added to the src/pages directory of your project, it is automatically available as a route based on its filename.

My article redirect is at /src/pages/redirect/articles/latest/index.astro.

---
// An example interface based on the YAML frontmatter I use in my markdown files.
// Your content might be different.
interface MarkdownFrontmatter {
    url: string;
    publishDate: Date;
    workInProgress: boolean;
};

// Again, your file system hierarchy might be different but
// relative to this file my markdown files are at this path.
const allArticles = Astro.fetchContent<MarkdownFrontmatter>('../../../../pages/posts/**/*.mdx');

// Filter out articles I don't want to be considered the "latest".
// Sort by latest and take the first.
const latestArticle = allArticles
    .sort((a, b) => new Date(b.publishDate).valueOf() - new Date(a.publishDate).valueOf())
    .filter(a => !a.workInProgress)
    [0];

const articleUrl = `${ Astro.site.origin }${ latestArticle?.url || '/articles' }`;
---

<head>
    <meta http-equiv="refresh" content={ `0; url=${ articleUrl }` } />
</head>

It’s worth pointing out that I do have a BaseHead component that abstracts away the need for dealing with head like I’m doing here - however given the special use case that component is not being used for the redirect.

You can see this in action right here. The following link /redirect/articles/latest redirects to my latest article. Success! As a bonus, as most social media sites follow <meta> they also correctly generate the right card for the latest article and not for the redirect page itself.

Conclusion

That’s about it! Simple and straightforward. I’m using default browser functionality with zero client side Javascript for the redirect. This means a couple of things:

  • Minimal payload sent to the user’s device meaning less time spent waiting for the redirect to occur
  • Such a universal concept can be built with any static site generator that lets you query for site content (Astro.fetchContent)

This could be expanded on easily for any type of content on your site, posts, projects, newly added products for sale, etc.

I hope that this redirect functionality will prove useful to you. Let me know how you use it!

Alternatives

I run my site on Netlify which does have redirect functionality however that would mean needing to write to a file as part of the build. Not a big deal but still an extra step.

Share:

Need help with your software project? Let's talk

Stay up to date

Subscribe to my newsletter to stay up to date on my articles and projects