August 2, 2023
getStaticPaths()
getStaticPaths()
is an API provided by both NextJS and Astro for generating routes. In other words, it generates valid urls.
It returns an array of valid routes, where each valid route is an object containing a params
field and props
field. The params
field is the important one since it describes the valid url path.
Borrowing directly from the tutorial, here’s a naive use of it.
// src/pages/tags/[tag].astro
export async function getStaticPaths() {
return [
{ params: { tag: "astro" } },
{ params: { tag: "successes" } },
{ params: { tag: "community" } },
{ params: { tag: "blogging" } },
{ params: { tag: "setbacks" } },
{ params: { tag: "learning in public" } },
];
}
This function creates the following routes:
Of course, this doesn’t take advantage of the full power of generating valid url routes dynamically. Later in the tutorial we see a better example.
export async function getStaticPaths() {
const allPosts = await Astro.glob('../posts/*.md');
const uniqueTags = [...new Set(allPosts.map((post) =>
post.frontmatter.tags).flat()
)];
return uniqueTags.map((tag) => {
const filteredPosts = allPosts.filter((post) =>
post.frontmatter.tags.includes(tag)
);
return {
params: { tag },
props: { posts: filteredPosts },
};
});
}
This function automatically creates a new page for each tag without having to hardcode it like in the first example. Much better.
[...new Set()]
This is a new pattern I also discovered from reading the Astro tutorial. You can see it used in the second example above.
const uniqueTags = [...new Set(allPosts.map((post) =>
post.frontmatter.tags).flat()
)];
First, there isn’t any Set
literal syntax in JS, so we have to call the constructor with the new
keyword in order to instantiate a Set
.
Second, the ...
before new
just means de-structuring the Set
back into an array. The ...
spread operator applies to the newly constructed Set
, not to the new
keyword.
This pattern is useful if we want to remove duplicates in an array. We convert it into a Set
and then immediately back into an array. Voila.1
The example in the tutorial has an added complication that we’re reducing a nested array with duplicates into a flat array without duplicates. So in the Set()
constructor there is an expression that involves map
to create the nested array and .flat()
to flatten it. ↩