1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Next.js/microCMS】microcms-js-sdk使用時にnot-found.jsで404ページを表示できないケースとその対策例

1
Posted at

こんにちは。

個人開発で作成しているmicroCMSとNext.jsを利用したブログサイトにおいて、Next.jsの404ページ表示用コンポーネントであるnot-found.jsnot-found.tsx)を記載したにも関わらず404ページが表示できずにエラーになる事象が起きました。

その事象・原因および解決法について備忘録代わりに記載いたします。

発生したエラー

Next.jsの公式ドキュメント通り、not-found.tsxappフォルダ直下に以下のように配置しました。

app/not-found.tsx
// コードはNext.js公式ドキュメントのものを転載
import Link from 'next/link'
 
export default function NotFound() {
  return (
    <div>
      <h2>Not Found</h2>
      <p>Could not find requested resource</p>
      <Link href="/">Return Home</Link>
    </div>
  )
}

またnot-found.tsx作成時のフォルダ構成は以下のような形でした。

app
- page.tsx
- layout.tsx
- not-found.tsx
- [id]
    - page.tsx

この状態でlocalhost:3000/hogeのように存在しないフォルダやidのURLを記載したところ、404ページではなく500エラーとなり、以下のエラーが発生しました。

fetch API response status: 404

原因と対策

結論としては、原因はpage.tsxの例外処理として404処理を呼び出す関数を記載していないことでした。

libs/client.js
// microcms-js-sdkを使用。ドメインとAPIキーを取得し、client定数に登録
import { createClient } from 'microcms-js-sdk';

if (!process.env.MICROCMS_SERVICE_DOMAIN) {
  throw new Error('MICROCMS_SERVICE_DOMAIN is required');
}

if (!process.env.MICROCMS_API_KEY) {
  throw new Error('MICROCMS_API_KEY is required');
}

export const client = createClient({
  serviceDomain: process.env.MICROCMS_SERVICE_DOMAIN,
  apiKey: process.env.MICROCMS_API_KEY,
});
[id]/page.tsx
import Link from 'next/link';
import { client } from '../../libs/client'

export default async function Page({ params }) {
  const { id } = await params;

  async function getBlogDetail() {
    const data = await client.get({
      endpoint: 'blogs',
      contentId: id,
    });
    return data;
  }

  const contents = await getBlogDetail();

  return (
    <>
     // ここにブログ記事の内容を出力するためのコードが入ります
    </>
  )
} 

Next.jsのドキュメントにもある通り、本来はnotfound用の関数は別途スローさせる必要がありました。

not-foundファイルは、ルートセグメント内でnotFound関数がスローされた場合にUIを描画するために使用されます。カスタムUIを提供するだけでなく、Next.jsはストリーミングレスポンスの場合は200のHTTPステータスコードを、非ストリーミングレスポンスの場合は404を返します。
引用元:https://nextjsjp.org/docs/app/api-reference/file-conventions/not-found
※太字は筆者

[id]/page.tsxのページパラメータの取得関数には例外処理が含まれていなかったため、404へのルートではなく500エラーが発生していたということでした。

対策

page.tsxのブログ情報取得関数に例外処理をつけ、例外処理の中でnotFound関数を返すことで404ページを意図通りに出力できました。

[id]/page.tsx
import Link from 'next/link';
import { client } from '../../libs/client'
+ import { notFound } from 'next/navigation';

export default async function Page({ params }) {
  const { id } = await params;

  async function getBlogDetail() {
  // try...catch...節を追加
    try {
      const data = await client.get({
        endpoint: 'blogs',
        contentId: id,
      });
      return data;
    } catch {
      notFound();
    }
  }

  const contents = await getBlogDetail();

  return (
    <>
     // ここにブログ記事の内容を出力するためのコードが入ります
    </>
  )
} 

最後に

ここまで読んでいただきありがとうございます。

エラーハンドリング系の関数は、単にファイルを追加するだけでなく関数が果たす役割・エラー処理の全体像まで掴んで実装することが重要とわかりました。

参考資料

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?