Astro
Creating dynamic routes for each post
Updated:
Now that we can successfully get our posts from Strapi, we need to tell Astro how to create a page for each post. This is where dynamic routes come in.
Slug dynamic route file
Create a new file called [slug].astro
in src/pages/posts
.
Copy and paste contents from src/pages/posts/index.astro
into this file.
// src/pages/posts/index.astro
---
const response = await fetch("http://127.0.0.1:1337/api/posts?populate=*");
const { data } = await response.json();
---
<h1>The Blog</h1>
{
data.map((post) => (
<>
<h2>{post.attributes.title}</h2>
<p>{post.attributes.body}</p>
<img
src={`http://127.0.0.1:1337${post.attributes.image.data.attributes.formats.large.url}`}
alt={post.attributes.image.data.attributes.name}
/>
</>
))
}
The reason for doing this is a lot of this code is reusable, and it will save us some time.
getStaticPaths()
If you remember from the earlier chapter on static and dynamic routes, we need to use the getStaticPaths() to generate our dynamic routes.
Update the src/pages/posts/[slug].astro
file to look like this:
---
export async function getStaticPaths() {
const response = await fetch("http://127.0.0.1:1337/api/posts?populate=*");
const { data } = await response.json();
return data.map((post) => {
return {
params: { slug: post.attributes.slug },
props: { post },
};
});
}
const { post } = Astro.props;
---
<h1>The Blog</h1>
Let’s break down what is happening inside the getStaticPaths() function.
First, we are using fetch to get our posts from our API from Strapi
const response = await fetch('http://127.0.0.1:1337/api/posts?populate=*')
Next, we get the data from our endpoint as a JavaScript object.
const { data } = await response.json()
Finally, we use map()
to iterate over each post and return
a new object with a params
and props
property.
return data.map((post) => {
return {
params: { slug: post.attributes.slug },
props: { post },
}
})
- The
params
property is an object with aslug
property, which Astro will use to generate our routes dynamically. - The
props
property contains all our data from each post, like the title, slug, body, and image.
The final line in the JS script section is:
const { post } = Astro.props
This is getting the post
variable from the object we return just above it.
return data.map((post) => {
return {
params: { slug: post.attributes.slug },
props: { post }, // creating the post data as a prop
}
})
const { post } = Astro.props // accessing the post data from props
Updating the template
Now we can update the template section with the following to render our post data.
---
export async function getStaticPaths() {
const response = await fetch("http://127.0.0.1:1337/api/posts?populate=*");
const { data } = await response.json();
return data.map((post) => {
return {
params: { slug: post.attributes.slug },
props: { post },
};
});
}
const { post } = Astro.props;
---
<h2>{post.attributes.title}</h2>
<p>{post.attributes.body}</p>
<img
src={`http://127.0.0.1:1337${post.attributes.image.data.attributes.formats.large.url}`}
alt="alt={post.attributes.image.data.attributes.name}"
/>
Now open your browser to http://localhost:3000/posts/my-first-post
or whatever the slug for one of your posts is, and you should see your post.
Wrap up
In this lesson, we learned how to generate dynamic routes for each post from Strapi’s REST API.
In the next lesson, we will configure Strapi to use GraphQL and learn how to use GraphQL in Astro.