If a page has dynamic routes
(documentation) and uses
getStaticProps it needs to define a list of paths that have to be
rendered to HTML at build time.
If you export an async function called getStaticPaths from a page that
uses dynamic routes, Blitz will statically pre-render all the paths
specified by getStaticPaths.
export async function getStaticPaths() {
return {
paths: [
{ params: { ... } } // See the "paths" section below
],
fallback: true or false // See the "fallback" section below
};
}paths key (required)The paths key determines which paths will be pre-rendered. For example,
suppose that you have a page that uses dynamic routes named
app/posts/pages/posts/[id].js. If you export getStaticPaths from this
page and return the following for paths:
return {
paths: [
{ params: { id: '1' } },
{ params: { id: '2' } }
],
fallback: ...
}Then Blitz will statically generate posts/1 and posts/2 at build time
using the page component in app/posts/pages/posts/[id].js.
Note that the value for each params must match the parameters used in
the page name:
app/posts/pages/posts/[postId]/[commentId], then
params should contain postId and commentId.pages/[...slug],
then params should contain slug which is an array. For example, if
this array is ['foo', 'bar'], then Blitz will statically generate the
page at /foo/bar.null, [],
undefined or false to render the root-most route. For example, if
you supply slug: false for pages/[[...slug]], Blitz will statically
generate the page /.fallback key (required)The object returned by getStaticPaths must contain a boolean fallback
key.
fallback: falseIf fallback is false, then any paths not returned by getStaticPaths
will result in a 404 page. You can do this if you have a small number
of paths to pre-render - so they are all statically generated during build
time. It’s also useful when the new pages are not added often. If you add
more items to the data source and need to render the new pages, you’d need
to run the build again.
Here’s an example which pre-renders one blog post per page called
app/posts/pages/posts/[id].js. The list of blog posts will be fetched
from your database or a CMS and returned by getStaticPaths . Then, for
each page, it fetches the data for a single post using getStaticProps.
// app/posts/pages/posts/[id].js
function Post({post}) {
// Render post...
}
// This function gets called during pre-rendering
export async function getStaticPaths() {
// 1. Use a blitz query to get all posts
// 2. Or call an external API endpoint to get posts
const posts = /* ... */
// Get the paths we want to pre-render based on posts
const paths = posts.map((post) => ({
params: {id: post.id},
}))
// We'll pre-render only these paths at build time.
// { fallback: false } means other routes should 404.
return {paths, fallback: false}
}
// This also gets called at build time
export async function getStaticProps({params}) {
// params contains the post `id`.
// If the route is like /posts/1, then params.id is 1
const post = /* get one post */
// Pass post data to the page via props
return {props: {post}}
}
export default Postfallback: trueIf fallback is true, then the behavior of getStaticProps changes:
getStaticPaths will be rendered to HTML at
build time.getStaticProps.In the “fallback” version of a page:
router.isFallback will be true.Here’s an example that uses isFallback:
// app/posts/pages/posts/[id].js
import {useRouter} from "blitz"
function Post({post}) {
const router = useRouter()
// If the page is not yet generated, this will be displayed
// initially until getStaticProps() finishes running
if (router.isFallback) {
return <div>Loading...</div>
}
// Render post...
}
// This function gets called at build time
export async function getStaticPaths() {
return {
// Only `/posts/1` and `/posts/2` are generated at build time
paths: [{params: {id: "1"}}, {params: {id: "2"}}],
// Enable statically generating additional pages
// For example: `/posts/3`
fallback: true,
}
}
// This also gets called at build time
export async function getStaticProps({params}) {
// params contains the post `id`.
// If the route is like /posts/1, then params.id is 1
const post = /* ... */
// Pass post data to the page via props
return {props: {post}}
}
export default Postfallback: true useful?fallback: true is useful if your app has a very large number of static
pages that depend on data (think: a very large e-commerce site). You want
to pre-render all product pages, but then your builds would take forever.
Instead, you may statically generate a small subset of pages and use
fallback: true for the rest. When someone requests a page that’s not
generated yet, the user will see the page with a loading indicator.
Shortly after, getStaticProps finishes and the page will be rendered
with the requested data. From now on, everyone who requests the same page
will get the statically pre-rendered page.
This ensures that users always have a fast experience while preserving fast builds and the benefits of Static Generation.
fallback: true will not update generated pages, for that take a look
at
Incremental Static Regeneration.
fallback: 'blocking'If fallback is 'blocking', new paths not returned by getStaticPaths
will wait for the HTML to be generated, identical to SSR (hence why
blocking), and then be cached for future requests so it only happens
once per path.
getStaticProps will behave as follows:
getStaticPaths will be rendered to HTML at
build time by getStaticProps.fallback: 'blocking' will not update generated pages by default. To
update generated pages, use
Incremental Static Regeneration
in conjunction with fallback: 'blocking'.
getStaticPaths?You should use getStaticPaths if you’re statically pre-rendering pages
that use dynamic routes.
GetStaticPathsFor TypeScript, you can use the GetStaticPaths type from blitz:
import { GetStaticPaths } from "blitz"
export const getStaticPaths: GetStaticPaths = async () => {
// ...
}getStaticPropsWhen you use getStaticProps on a page with dynamic route parameters, you
must use getStaticPaths.
You cannot use getStaticPaths with getServerSideProps.
getStaticPaths only runs at build time on server-side.
getStaticPaths can only be exported from a page. You can’t export it
from non-page files.
Also, you must use export async function getStaticPaths() {} — it will
not work if you add getStaticPaths as a property of the page
component.
In development (blitz dev), getStaticPaths will be called on every
request.