Next.js の SSG で 404 ページを適切に表示する
はじめに
こんにちは kimizuy です。
今回は fallback
と notFound
の使い方をまとめて Next.js の SSG で 404 ページを適切に表示する方法をご紹介します。
ここで言う「適切」とはビルド時のみならず next dev
したときにもエラーが出ない状態を意味します。
「next build
は問題ないのに next dev
ではデータ取得に失敗したときの TypeError
が出てしまう!」という場合にも役立つと思います。
前提: fallback が何を指すか
Next.js の SSG の場合、「fallback」には 2 通りの使われ方あります。
- ページコンポーネントに返却される props が空のときに表示する状態
getStaticPaths
の返り値として指定するパラメータ
本記事では以降、後者の fallback
パラメータの挙動パターンを解説します。
fallback: false
getStaticPaths が返さないパスは常に 404 ページが返されます。
next dev
のときに正しい URL のはずなのに 404 ページが表示されてしまうのは、getStaticPaths
が毎回実行されており、存在しないパスを指定した状態が発生しているためです。
If fallback is false, then any paths not returned by getStaticPaths will result in a 404 page.
https://nextjs.org/learn/basics/dynamic-routes/dynamic-routes-details
In development (next dev), getStaticPaths will be called on every request.
https://nextjs.org/learn/basics/dynamic-routes/dynamic-routes-details
fallback: true
ISR で動的にページを更新する際に使います。また next/router
の isFallback
と組み合わせることを前提にしています。いったん isFallback
内の状態を返し、バックグラウンドで getStaticProps
を実行してデータ取得が完了したらページを再レンダリングします。
import { useRouter } from "next/router"
const Page = (props) => {
const router = useRouter()
if (router.isFallback) {
return <div>Loading...</div>
}
return <div>{props.data}</div>
}
後続の URL アクセスはキャッシュされたページが返却されます。
ビルド時に生成されていないパスは 404 ページにリダイレクトされません。
このとき getStaticProps
でデータ取得が失敗すると以下のエラーが発生するため notFound
を使う必要があります。
Application error: a client-side exception has occurred (see the browser console for more information).
export function getStaticProps() {
const data = getData()
return {
props: {
data
},
// データが取得できなかった場合は 404 ページとステータスコード 404 が返却されます
notFound: !data
}
}
参考: https://github.com/vercel/next.js/discussions/10960#discussioncomment-1201
そもそも notFound とは
Next.js 10 で追加されました。
それまではクライアント側でデータの有無を判定する方法しかなく実際は 404 の状態なのにステータスは 200 になってしまう状況がありました。
参考: https://nextjs.org/blog/next-10#redirect-and-notfound-support-for-getstaticprops–getserversideprops
fallback: "blocking"
fallback: true
とは違い、フォールバックの状態を返さないでページ生成を完了するまでクライアントの操作をブロックします。
後続の URL アクセスはキャッシュされたページが返却されます。
fallback: blocking
で無効な URL を指定した場合、500 エラーが発生します。この場合も notFound
を追加して 404 ページが適切に表示されるようにします。
export const getStaticPaths = async () => {
return {
paths: [],
fallback: "blocking"
}
}
export function getStaticProps() {
const data = getData()
return {
props: {
data
},
notFound: !data
}
}
おわりに
今回は fallback
と notFound
を組み合わせて 404 ページを適切に表示する方法についてまとめました。
以上、お読みいただきありがとうございました。
今すぐの転職でなくてもOKです!まずはお話しませんか?
現在弊社では一緒にお仕事をしてくださるエンジニアさんやデザイナーさんを積極募集しています。まずはカジュアルな面談で、お互いに大事にしていることをお話できたらうれしいです。詳しい応募要項は以下からチェックしてください。
- React, Next.js を得意とするフロントエンドエンジニア募集要項
- シニアクラスのフロントエンドエンジニア募集要項
- 抽象的な物事を具体的な機能にビジュアライズできるUIデザイナー募集要項
- UIデザイナーとして手ざわりのいいUIを作りたい業務委託パートナーさん募集(Wantedly)
パートナー契約へのお問い合わせもお仕事へのお問い合わせも、どちらもいつでも大歓迎です。まずはオンラインでの面談でお話しましょう。ぜひお気軽にお問い合わせください!
話をしてみたい!