getStaticProps API
If you export an
async
function called getStaticProps
from a page, Blitz will pre-render this page at build time using the props returned by getStaticProps
.export async function getStaticProps(context) {return {props: {}, // will be passed to the page component as props}}
The
context
parameter is an object containing the following keys:params
contains the route parameters for pages using dynamic routes. For example, if the page name is[id].js
, thenparams
will look like{ id: ... }
. To learn more, take a look at the Dynamic Routing documentation. You should use this together withgetStaticPaths
, which we’ll explain later.preview
istrue
if the page is in the preview mode andfalse
otherwise. See the Preview Mode documentation.previewData
contains the preview data set bysetPreviewData
. See the Preview Mode documentation.
Note: You can import modules in top-level scope for use in
getStaticProps
. Imports used ingetStaticProps
will not be bundled for the client-side, as explained below.
Simple Example
Example: Your blog page needs to load it's data from your database or from a CMS (content management system).
function Blog({posts}) {// Render posts...}// This function gets called during pre-renderingexport async function getStaticProps() {// 1. Use a Blitz query// 2. Directly access your database// 3. Or call an external API endpoint to get postsconst posts = /* ... */// By returning { props: posts }, the Blog component// will receive `posts` as a prop at build timereturn {props: {posts,},}}export default Blog
When should I use getStaticProps
?
You should use
getStaticProps
if:- The data for the page is not private and can be publicly available
- The data comes from headless CMS.
- The page must be pre-rendered (for SEO) and be very fast —
getStaticProps
generates HTML and JSON files, both of which can be cached by a CDN for performance.
TypeScript: Use GetStaticProps
For TypeScript, you can use the
GetStaticProps
type from blitz
:import {GetStaticProps} from "blitz"export const getStaticProps: GetStaticProps = async (context) => {// ...}
If you want to get inferred typings for your props, you can use
InferGetStaticPropsType<typeof getStaticProps>
, like this:import {InferGetStaticPropsType} from "blitz"type Post = {author: stringcontent: string}export const getStaticProps = async () => {const res = await fetch("https://.../posts")const posts: Post[] = await res.json()return {props: {posts,},}}function Blog({posts}: InferGetStaticPropsType<typeof getStaticProps>) {// will resolve posts to type Post[]}export default Blog
Reading files: Use process.cwd()
Files can be read directly from the filesystem in
getStaticProps
.In order to do so you have to get the full path to a file.
Since Blitz compiles your code into a separate directory you can't use
__dirname
as the path it will return will be different from the pages directory.Instead you can use
process.cwd()
which gives you the directory where Blitz is being executed.import fs from "fs"import path from "path"// posts will be populated at build time by getStaticProps()function Blog({posts}) {return (<ul>{posts.map((post) => (<li><h3>{post.filename}</h3><p>{post.content}</p></li>))}</ul>)}// This function gets called at build time on server-side.// It won't be called on client-side, so you can even do// direct database queries. See the "Technical details" section.export async function getStaticProps() {const postsDirectory = path.join(process.cwd(), "posts")const filenames = fs.readdirSync(postsDirectory)const posts = filenames.map((filename) => {const filePath = path.join(postsDirectory, filename)const fileContents = fs.readFileSync(filePath, "utf8")// Generally you would parse/transform the contents// For example you can transform markdown to HTML herereturn {filename,content: fileContents,}})// By returning { props: posts }, the Blog component// will receive `posts` as a prop at build timereturn {props: {posts,},}}export default Blog
Technical details
Only runs at build time
Because
getStaticProps
runs at build time, it does not receive data that’s only available during request time, such as query parameters or HTTP headers as it generates static HTML.Write server-side code directly
Note that
getStaticProps
runs only on the server-side. It will never be run on the client-side. It won’t even be included in the JS bundle for the browser. That means you can write code such as direct database queries without them being sent to browsers. You should not fetch an API route from getStaticProps
— instead, you can write the server-side code directly in getStaticProps
.You can use
this tool to verify what Blitz eliminates from the client-side bundle.Statically Generates both HTML and JSON
When a page with
getStaticProps
is pre-rendered at build time, in addition to the page HTML file, Blitz generates a JSON file holding the result of running getStaticProps
.This JSON file will be used in client-side routing through
<Link>
or next/router
(documentation). When you navigate to a page that’s pre-rendered using getStaticProps
, Blitz fetches this JSON file (pre-computed at build time) and uses it as the props for the page component. This means that client-side page transitions will not call getStaticProps
as only the exported JSON is used.Only allowed in a page
getStaticProps
can only be exported from a page. You can’t export it from non-page files.One of the reasons for this restriction is that React needs to have all the required data before the page is rendered.
Also, you must use
export async function getStaticProps() {}
— it will not work if you add getStaticProps
as a property of the page component.Runs on every request in development
In development (
blitz start
), getStaticProps
will be called on every request.Preview Mode
In some cases, you might want to temporarily bypass Static Generation and render the page at request time instead of build time. For example, you might be using a headless CMS and want to preview drafts before they're published.
This use case is supported by Blitz by the feature called Preview Mode. Learn more on the
Preview Mode documentation.