When adding dynamic content to Next.js, there may be instances where you need to dynamically generate a page that requires data upfront. One way to achieve this is by utilizing the getInitialProps
function. In this blog post, we will explore how to feed data to a Next.js component using getInitialProps
.
First, let’s take a look at an example where we encountered an issue while trying to get data from a JSON file for a dynamically generated post page. Here’s the code snippet:
import { useRouter } from 'next/router'
import posts from '../../posts.json'
export default () => {
const router = useRouter()
const post = posts[router.query.id]
return (
<>
<h1>{post.title}</h1>
<p>{post.content}</p>
</>
)
}
Unfortunately, this approach led to an error. So, how do we solve this problem and make Server-Side Rendering (SSR) work for dynamic routes?
To provide the component with the necessary props, we can use the getInitialProps
function, which needs to be attached to the component. Here’s how:
const Post = () => {
//...
}
Post.getInitialProps = () => {
//...
}
export default Post
The getInitialProps
function takes an object as its argument, which contains several properties. For our current purpose, we are interested in the query
object, which we previously used to get the post ID. We can extract this object using object destructuring syntax as follows:
Post.getInitialProps = ({ query }) => {
//...
}
Now, we can return the post from within this function:
Post.getInitialProps = ({ query }) => {
return {
post: posts[query.id]
}
}
Furthermore, we can remove the import of useRouter
and access the post from the props
property passed to the Post
component:
import posts from '../../posts.json'
const Post = props => {
return (
<div>
<h1>{props.post.title}</h1>
<p>{props.post.content}</p>
</div>
)
}
Post.getInitialProps = ({ query }) => {
return {
post: posts[query.id]
}
}
export default Post
By implementing these changes, the error will be resolved, and SSR will be functional as expected.
It’s important to note that getInitialProps
is executed on both the server-side and the client-side. This means that when navigating to a new page using the Link
component, the function will be executed on the client-side. Additionally, getInitialProps
receives the following properties in the context object:
pathname
: thepath
section of the URLasPath
: a string of the actual path (including the query) shown in the browser
For example, calling http://localhost:3000/blog/test
will result in the following values for pathname
and asPath
respectively:
/blog/[id]
/blog/test
If server-side rendering is involved, getInitialProps
will also receive the following properties:
req
: the HTTP request objectres
: the HTTP response objecterr
: an error object
These properties are familiar if you have experience with Node.js coding.