NextJS is a JavaScript framework that uses ReactJS for rendering UI in web applications. This framework comes with many great features like server-side rendering, static-site generation, image optimizations, routing, and many more. But, there is something that annoys me terribly and that is handling errors in server-side rendering. This is why we will be looking into this problem in the rest of this article.
1. Quick intro into server-side rendering with the getServerSideProps
If you export getServerSideProps in your page component, on the request, it will try to generate the HTML that is returned as a response.
export default function ServerSideProps({ person }) {
const { firstName, lastName } = person;
return (
<>
Hello {firstName} {lastName}
</>
)
}
export async function getServerSideProps(context) {
return {
props: {
person: { firstName: "John", lastName: "Doe" }
}, // will be passed to the page component as props
}
}
Take a look at the example above. It is a simple component taking a person's data as props. Those values are sent from the getServerSideProps. When the user requests the route, those data are prepared, sent to the component for rendering, and then the result is sent as a response to the user.
2. 404, page not found
In the example above, you might have noticed how the getServerSideProps function returns the object, and the data needed for the component is stored under the property called props. That is not the only property it can return. Another property it can return is called notFound which type is Boolean. If you set this value as true, the response status code value is 404 and displayed is appropriate page. This can be the default NextJS 404 page, or you could create your own custom 404 page.
export async function getServerSideProps(context) {
const personId = context.params.id;
if(personId === "4") {
return {
notFound: true,
}
}
const personData = await fetchData(personId);
return {
props: {
person: personData
},
}
}
Take a look at the example above showing only the getServerSideProps method. Assume we have the same ReactJS component as before, and that we know, a person with the id value 4 does not exist. In that case, all it is returning is an object with this property set to true. In other cases, we could explicitly set it to false, but that is the default value and there is no need for it.
3. Custom status code responses
The previous example showed a situation when we need to return a page not found. But what happens when we need to send some custom error? This is where things become messy. There is no return for custom status values. But there are tricks we can use. The getServerSideProps function receives a single argument, context. And among other properties, it receives a response object. There we can set specific status code values.
export async function getServerSideProps(context) {
const personId = context.params.id;
if (personId === "4") {
return { notFound: true, }
}
if (personId === "5") {
context.res.statusCode = 503;
return {
props: {
error: { status: 503, message: "Service unavailable" }
}
}
}
const personData = await fetchData(personId);
return {
props: {
person: personData
},
}
}
What you might notice above, after setting the status, I also set props. The reason for that is that unless you are returning notFound, NextJS will still try to render your original component. And that means, we also need to adjust our page component.
export default function ServerSideProps({person, error}) {
if (error) {
return (
<div><b>{error.status}</b> {error.message}</div>
)
}
const {firstName, lastName} = person;
return (
<div>
Hello {firstName} {lastName}
</div>
)
}
Above, the component is extended with an error, and in that case, it will return different content showing the error. I know this is not an ideal situation, but at the moment it is the best option there is.
4. Return redirect
The last item to cover is redirecting. I already mentioned that the getServerSideProps function returns an object that can have properties props and notFound. There is one more, and that one is used for redirection.
if (personId === "6") {
return {
redirect: {
destination: '/server-side-props/errors/1',
permanent: false,
}
}
}
We could add the example above to our getServerSideProps function, and if you try to open the URL for the person with id value 6, it will redirect you to the page for person with the id 1. You may notice, there is another property called permanent. That one is used to select which redirect status it will return so that browsers and search engines can cache redirect forever, or just this one time. True means cache it and redirect forever (status 308) and false means just redirect and don’t cache (status 307).
Conclusion
Server-side rendering is a very useful feature that provides us with many benefits. However, sometimes in the software, things just go wrong. Requests fail, a database connection is lost, 3rd party API is unavailable and we need to be able to handle those situations properly. I hope this article helps you with that. The code used in the examples above can be found in my GitHub repository.
For more, you can follow me on Twitter, LinkedIn, GitHub, or Instagram.