ポートフォリオサイトをヘッドレスWordPress+Next.jsで作り直した話 (3) Next.js実装編

執筆者:

カテゴリ:

シリーズ3回目です。今回はNext.js側の実装と、そのなかで実際に踏んだ不具合について書きます。

データ取得の流れ

WordPress側にWPGraphQLでAPIを用意したので、Next.js側はそれを叩くだけ…なのですが、クエリを文字列のまま書くとレスポンスの型が付かず補完も効きません。そこで GraphQL Codegen を導入し、次のような流れでデータを取得しています。

// src/lib/queries/projects.ts
export const GET_PROJECTS = graphql(/* GraphQL */ `
  query GetProjects {
    projects(first: 100) {
      nodes {
        id
        title
        content
        uri
        featuredImage { node { sourceUrl altText } }
        projectCategories { nodes { name slug } }
        projectDetail { role period toolsused }
      }
    }
  }
`);

graphql() タグでクエリを書いておき、npm run codegen を実行すると、クエリごとに型安全な戻り値の型が自動生成されます。ACFのフィールドを追加・変更してWordPress側のスキーマが変わった場合も、コマンド一発で型を追従させられるのが便利なところです。あとはこれを Server Component の中で await して呼び出すだけなので、データ取得部分はシンプルに書けました。

GraphQLクエリからCodegen、Server Component、レンダリングまでのデータフロー

ハマった不具合: 日本語スラッグが404になる

実装を進めるなかで一番手こずったのが、実績の詳細ページが軒並み404になるという不具合でした。原因を辿ってみると、WordPress側で実績のスラッグ(URLの末尾部分)を日本語のまま(例:「wordpressオリジナルテーマ作成」)にしていたことが原因でした。Next.jsの動的ルート([slug]/page.tsx)がURLからパラメータを受け取る際、環境によってスラッグがパーセントエンコードされたまま渡ってくることがあり、WPGraphQL側の nodeByUri がそれをうまく解決できずにnullを返していた、というのが実態です。

対処としては、実績のスラッグをすべて英数字(ローマ字)にリネームしたうえで、念のためNext.js側でも decodeURIComponent(params.slug) を挟むようにしました。

const decodedSlug = decodeURIComponent(params.slug);
const uri = `/projects/${decodedSlug}/`;
const project = await getProjectByUri(uri);

この不具合については、原因調査から検証までをもう少し詳しく別記事にまとめてあります。よければあわせてどうぞ。

日本語スラッグの投稿がNext.jsで404になった話 →

今回のまとめ

Codegenのおかげでデータ取得部分は型安全に保てましたが、「URLエンコーディング」のような地味な足回りの部分は結局手を動かして初めて気づく類の問題でした。次回は、デザインをもとのサイトに近づける調整と、このブログ機能の追加について書きます。

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です