Using getStaticProps and getStaticPaths with TypeScript - Next.js

Search for a command to run...

No comments yet. Be the first to comment.
Do you ever watch your view count rise and wonder which posts are being read the most? I know I did. That is one reason why I chose to develop my own Dev.to analytics dashboard to display historical data such as view, reaction and follower increase ...

Ever wondered if you can share interfaces, types and functions between TypeScript projects? I'm currently developing a project consisting of two separate TypeScript applications, one being a React.js dashboard and the other an Azure Function app writ...

Usually, when adding icons to a website, I'll use React-icons. There are times, however, when I prefer to copy an exact SVG from a website. Downloading an SVG isn't as easy as downloading an image on a website. Fortunately, SVG Export extracted them ...

The final weekend of January 2021 was uneventful in comparison with other years - in the UK we were in full lockdown due to the Coronavirus. It was, however, the perfect opportunity to completely rewrite my personal website. Why? I decided to redesig...

My personal website is built on Next.js and uses both the getStaticProps and getStaticPaths functions to dynamically generate the /blog/ and /portfolio/ pages at build time. While updating both methods to use their proper TypeScript types, following the documentation, I ran into an error when reading the parameter that I was passing from getStaticPaths into getStaticProps.
The error that appeared was:
Property 'slug' does not exist on type 'ParsedUrlQuery | undefined'
After doing some research and finding a discussion on the Next.js GitHub regarding this issue, I recognised it was a gap in their documentation. It explains how to add the type to getStaticProps when used on its own but it doesn't demonstrate how to access the property you've declared in getStaticPaths.
getStaticProps and getStaticPaths are two methods that can be used for data fetching in Next.js. Briefly speaking getStaticProps lets you fetch data at build time and getStaticPaths enables you to specify dynamic routes to pre-render pages based on data.
For more information on these functions, read my post on different ways to fetch data in Next.js.
Using the example code below I will demonstrate the TypeScript error and advise you on how to fix it. I'm using the variable name slug to create the dynamic routes, but you could use anything - another common name is id.
import { GetStaticPaths, GetStaticProps } from 'next'
import { ParsedUrlQuery } from 'querystring'
export const getStaticPaths: GetStaticPaths = async () => {
const arr: string[] = ['slug1', 'slug2']
const paths = arr.map((slug) => {
return {
params: { slug },
}
})
return { paths }
}
export const getStaticProps: GetStaticProps = async (context) => {
// This is where the error occurs
const { slug } = context.params // Property 'slug' does not exist on type 'ParsedUrlQuery | undefined'
const props = fetch(`/api/${slug}`)
return { props }
}
Note the first line of the getStaticProps. Here we are attempting to access the slug variable that was created in getStaticPaths and returned inside the params object. This is the line that causes the error as context.params has the type ParsedUrlQuery | undefined and slug does not exist in ParsedUrlQuery.
const { slug } = context.params
Fortunately, fixing the issue is as simple as creating an interface that extends ParsedUrlQuery and contains a slug property.
interface IParams extends ParsedUrlQuery {
slug: string
}
Once we've added that to the file, we need to assert that context.params is of type IParams. This is done like so:
const { slug } = context.params as IParams
It's as simple as that! Just adding the IParams interface makes the TypeScript error disappear.
Updated example code:
import { GetStaticPaths, GetStaticProps } from 'next'
import { ParsedUrlQuery } from 'querystring'
interface IParams extends ParsedUrlQuery {
slug: string
}
export const getStaticPaths: GetStaticPaths = async () => {
const arr: string[] = ['slug1', 'slug2']
const paths = arr.map((slug) => {
return {
params: { slug },
}
})
return { paths }
}
export const getStaticProps: GetStaticProps = async (context) => {
const { slug } = context.params as IParams // no longer causes error
const props = fetch(`/api/${slug}`)
return { props }
}
If this post has helped you use Next.js together with TypeScript, react or let me know in the comments!
Thanks for reading!
Sources: