Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tk astro redirect #513

Merged
merged 13 commits into from
Jul 17, 2023
16 changes: 16 additions & 0 deletions .astro/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1735,6 +1735,22 @@ declare module 'astro:content' {
collection: "posts",
data: InferEntrySchema<"posts">
},
"2023-07-12-astro-redirects.md": {
id: "2023-07-12-astro-redirects.md",
slug: "creating-a-redirect-in-astro",
body: string,
collection: "posts",
data: InferEntrySchema<"posts">
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we tab these out so we don't get things like

},
},

or is that just like the way astro is

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file is automatically generated by Astro

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well it's gross and they should feel bad

},
"redirects": {
"gotopets.md": {
id: "gotopets.md",
slug: "show-me-cute-animals",
body: string,
collection: "redirects",
data: any
},
},

};
Expand Down
10 changes: 9 additions & 1 deletion src/components/Head.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Favicons from './Favicons.astro';
import { site } from '../data/config.json';
import '../sass/styles.scss';

const { title, description, image, permalink } = Astro.props;
const { title, description, image, permalink, redirect } = Astro.props;
---

<head>
Expand Down Expand Up @@ -58,6 +58,14 @@ const { title, description, image, permalink } = Astro.props;
/>
<meta itemprop="image" content={image ? image : site.default_image} />

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

<title>{title ? `${title} | RIMdev Blog` : site.title}</title>
<meta name="description" content={site.description} />
<link
Expand Down
2 changes: 1 addition & 1 deletion src/content/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const postsCollection = defineCollection({
twitter_text: z.string(),
image: z.string().default(site.default_image),
image_url: z.string().default(site.baseurl),
image_credit: z.string().default(site.site_name),
image_credit: z.string().default(site.site_name)
}),
});

Expand Down
160 changes: 160 additions & 0 deletions src/content/posts/2023-07-12-astro-redirects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
---
title: "Creating A Redirect in Astro"
slug: creating-a-redirect-in-astro
date: 2023-07-14 11:27:06
tags:
- frontend
- Astro
- SSG
categories:
- frontend
- css
twitter_text: "Creating A Redirect in Astro"
authors:
- Ted Krueger
image: https://images.unsplash.com/photo-1516979187457-637abb4f9353?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1770&q=80
image_url: https://unsplash.com/photos/eMP4sYPJ9x0
image_credit: Alexander Grey
---

Get to the point. [TLDR;](#using-dynamic-pages)

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](https://docs.astro.build/en/reference/errors/static-redirect-not-available/) 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](https://www.lloydatkinson.net/posts/2022/static-site-redirects-with-astro/) 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](#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`.

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

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

```js
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.

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

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

```html
<!-- 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](/redirect). Pretty cool.

This definitely works, but I feel like we could make it a little better. We can by using [Content Collections](https://docs.astro.build/en/guides/content-collections/) and [Dynamic Pages](https://docs.astro.build/en/core-concepts/routing/#example-dynamic-pages-at-multiple-levels).

## [Using 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:

```html
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.

```js
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.

```js
{
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](/show-me-cute-animals).
9 changes: 9 additions & 0 deletions src/content/redirects/gotopets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: "Sample Redirect"
slug: show-me-cute-animals
redirect:
url: "/the-pets-of-rimdev"
timing: 5
---

You should see cute animals in 5 seconds.
4 changes: 2 additions & 2 deletions src/layouts/MainLayout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import SearchModal from '../components/SearchModal.astro';
import Footer from '../components/Footer.astro';
import { site } from '../data/config.json';

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

<!DOCTYPE html>
<html lang="en">
<Head title={title} image={image} permalink={url} />
<Head title={title} image={image} permalink={url} redirect={redirect} />
<body class="background--white">
<Masthead
authorImage={authorImage}
Expand Down
84 changes: 53 additions & 31 deletions src/pages/[slug].astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,67 @@ import PostBy from '../components/PostBy.astro';
import PostAuthors from '../components/PostAuthors.astro';

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

const { entry } = Astro.props;
const { title, date, image, image_credit, image_url, authors, tags } = entry.data
const { title, date, image, image_credit, image_url, authors, tags, redirect } = entry.data
const { Content } = await entry.render();
---

<MainLayout
title={title}
image={image}
imageCredit={image_credit}
imageUrl={image_url}
url={entry.slug}
>
<div class="container" data-pagefind-body>
<article>
<h1 class="py-4 p-0 text--size-2xl">{title}</h1>

<div
class="author flex flex--align-center flex--justify-between py-2 border-b border-t border--color-base mb-4"
>
<p class="p-0 m-0">
Written by
<PostAuthors authors={authors} />
</p>
{
entry.collection === 'posts' ? (
<MainLayout
title={title}
image={image}
imageCredit={image_credit}
imageUrl={image_url}
url={entry.slug}
>
<div class="container" data-pagefind-body>
<article>
<h1 class="py-4 p-0 text--size-2xl">{title}</h1>

<div
class="author flex flex--align-center flex--justify-between py-2 border-b border-t border--color-base mb-4"
>
<p class="p-0 m-0">
Written by
<PostAuthors authors={authors} />
</p>
</div>

<Content />
</article>
<PostBy
date={date}
authors={authors}
tags={tags}
/>
<RelatedArticles currentTitle={title} tags={tags} />
</div>

<Content />
</article>
<PostBy
date={date}
authors={authors}
tags={tags}
/>
<RelatedArticles currentTitle={title} tags={tags} />
</div>
</MainLayout>
</MainLayout>
) : null
}
{
entry.collection === 'redirects' ? (
<MainLayout
title={title}
url={entry.slug}
redirect={redirect}
>
<div class="container" data-pagefind-body>
<article>
<Content />
</article>
</div>
</MainLayout>
) : null
}
12 changes: 12 additions & 0 deletions src/pages/redirect/index.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
import MainLayout from '../../layouts/MainLayout.astro';

const title = "You won't see this page.";
const image = "/images/default/rimdev-configyml.jpg";

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

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