Next.jsで対象ページの404ページを実装するときに、SSRをさせたかった。
デフォルトの404ページを使うと対応できず、悩んだため書いておく。
目次
Next.jsの404ページ
Next.jsの404ページはpages/404.jsを用意することで、404の時に表示されます。
ただし、getStaticPropsだけしか使えず、静的なページになります。
SSRが使えないので悩みどころです。
Routing: Custom Errors | Next.js
Override and extend the built-in Error page to handle custom errors.
対象ページでSSRして404ページを表示させる
対象ページの404ページをSSRさせるためには、getServerSideProps
の中でhttp status codeを404にしてreturnします。
これでクライアントレンダリングでstatusCodeで404かを判定してレンダリングする要素をかえることで対応します。
404かを判定するhookは作ったほうが良さそう。
export const getServerSideProps: GetServerSideProps = async (context) => {
context.res.statusCode = 404;
return {
props: {
statusCode: 404,
},
};
};
これだけでも動作はするんだけど、なぜか複数回のレンダリングが走り、画面がチラつく現象があった。
調べているとSSRが2回呼びされていた。
context.res.statusCode
を設定すると、SSRが2回呼び出され、ページ全体が再レンダリングされる問題を回避するために、下記コードへ変更した。
これは、client side からの発火で/_next/data/… のデータもリクエストとしてくるため、除外することで対応する。
export const getServerSideProps: GetServerSideProps = async (context) => {
const isServerSideRequest =
context.req?.url !== undefined &&
!context.req.url.match(/^\/_next\/data\/.*slug=.*$/);
if (context.res && isServerSideRequest) {
context.res.statusCode = 404;
return {
props: {
statusCode: 404,
},
};
}
return {
props: {
statusCode: 200,
},
};
};
Summary
Next.jsで詰まった時はまずは公式ドキュメントに目を通しています。バージョンによって変わっていることもあるのでまずは参照するようにするとよさそう。