Creating A Redirect in Astro

Written by Ted Krueger

Get to the point. TLDR;

We needed to redirect a current URL to a different page. In our case, we wanted /agenda to redirect to an event page. So, to explain it like you’re a five-year-old, who knows a decent amount of developer knowledge, when someone would go to website-name.com/agenda they would actually go to website-name.com/desired-page.

You used to be able to do this using the Astro.redirect method, but it has been deprecated as of version 2.6, unless you’re using Server Side Rendering then you’re good. If using static site generation (like we do) you can use this approach that Astro recommends using the meta refresh attribute.

Before I get into the nuts and bolts of the post, I must admit that my attention to detail in the Astro docs was pretty lacking because I missed them suggesting the use of the meta refresh. I did, however, see this in Lloyd Atkinson’s post on his blog. In his post, Atkinson shows us how he uses the meta refresh attribute to redirect to his latest blog post. In our case, we wanted our redirect to be specific so we didn’t need to worry about some of the extra stuff Lloyd was doing.

Creating The Redirect

I decided to start in the file that I would be redirecting from. For this post, I’ll create a redirect page.

- src
 - pages
  - redirect
   index.astro

In here, I’ll add a redirect variable. I want to drive some more traffic to our Pets of RIMdev page so I’ll set that URL to the value of the redirect. The frontmatter looks like this:

const redirect = "/the-pets-of-rimdev"

Now that we have our redirect defined, we need to get that info to the Head.astro component. We pass the parameters to the layout component we are using. In this case, it’s our MainLayout.astro.

<MainLayout title={title} image={image} redirect={redirect}>
  <h1>Redirects!</h1>
</MainLayout>

Let’s head to the MainLayout and add redirect to our props.

const { title, image, authorImage, author, imageCredit, imageUrl, url, redirect } = Astro.props;

Our Head.astro component is used inside the MainLayout file so we need to pass the redirect prop there as well.

<Head title={title} image={image} permalink={url} redirect={redirect} />

Inside our Head.astro component we want to add the meta refresh tag.

<!-- redirects -->
{redirect ? (
  <meta 
    http-equiv="refresh" 
    content={ `0; url=${ redirect }` } 
  />
) : null}

Here we check for redirect because not every page will have one so there’s no point to render this. The redirect is used in the content which tells the browser what page to redirect to. Check it out here. Pretty cool.

This definitely works, but I feel like we could make it a little better. We can by using Content Collections and Dynamic Pages.

Using Dynamic Pages

We already have a dynamic page, [slug].astro, created for our posts. This allows us to create specific slugs for our posts. We’ll use this for our redirects because we’ll want to specify slugs for these redirects. Our dynamic page lives right in our pages folder.

src
 - content
  - authors
  - posts
  - redirects
 - pages
  [slug].astro

Using Content Collections, we have a content folder inside our src directory. This is where we need to create a redirects folder. We can add our files or pages for each redirect in the redirects folder. Each file will represent an individual redirect. Because we’re using the dynamic [slug] page, we can name these .md files anything we want. This will help other devs know what the file is doing. So we can name our redirect, gotopets.md.

<!-- gotopets.md -->
---
title: "Sample Redirect"
slug: show-me-cute-animals
redirect: 
  url: "/the-pets-of-rimdev"
  timing: null
---

I created a redirect object in the frontmatter because I figured why not give someone the option to set the timing for the redirect. It might not always be instant or 0. In the meta tag in the head, however, it will default to 0 unless a timing function is specified. Take a look:

Head.astro

<!-- Add redirect to the list of props -->
const { title, description, image, permalink, redirect } = Astro.props;

<!-- redirects -->
{redirect ? (
  <meta 
    http-equiv="refresh" 
    content={ `${ redirect.timing ? redirect.timing : '0' }; url=${ redirect.url }` }
  />
) : null}

Our dynamic [slug].astro needs updates too.

export async function getStaticPaths() {
  const entries = [
    ...(await getCollection('posts')),
    ...(await getCollection('redirects')),
  ];
  return entries.map((entry) => ({
    params: { slug: entry.slug },
    props: { entry },
  }));
}

We need to add `redirects to the entries array. Then we’ll wrap our current Post related code checking for the posts collection. We’ll do the same thing for collections.

{
  entry.collection === 'redirects' ? (
    <MainLayout
      title={title}
      url={entry.slug}
      redirect={redirect}
    >
      <div class="container" data-pagefind-body>
        <article>
          <Content />
        </article>
      </div>
    </MainLayout>
  ) : null
}

Wanna see how it works? So you can see how it works, I’ll add a timing param of 5 seconds. Check this out show-me-cute-animals.

Published July 14, 2023 by

undefined avatar
Ted Krueger UI/UX Developer

Suggested Reading