Next.js App Routerの切り分け|layout・metadata・Server Actions
Next.js App Routerの不具合を、Server・Client Componentの境界、metadata、Server Actionsの認可に分けて確認します。最小コード例と失敗ケースの期待値を示します。
読了目安:3分

App Routerでエラーが出たら、まずServer ComponentとClient Componentの境界、metadataの定義場所、更新処理の認可を分けて確認します。このブログの依存設定はNext.js 16.2系です。別のバージョンを使っている場合は、そのバージョンの公式資料と照合してください。
layoutからpageへ移すだけでは直らない
layoutもpageも既定ではServer Componentです。useStateなどが必要な部分はClient Componentへ分けます。pageへ移すだけでクライアント専用APIが使えるわけではありません。Server and Client Components
説明用の最小例では、親をサーバー側に残し、ボタンだけを別ファイルにします。
// Counter.tsx
'use client';
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
// app/page.tsx (Counter.tsx is in the same directory)
import Counter from './Counter';
export default function Page() {
return <Counter />;
}
サーバー側のpageからCounterを読み込み、ボタンが0から1へ変わるか確かめます。動かなければ最初のConsoleエラーを確認し、必要な子だけを切り出せているか見直します。実アプリの秘密情報やデータ取得をそのままクライアント側へ移さないでください。
metadataは本文とURLを照合する
metadataとgenerateMetadataはServer Componentで扱います。動的生成を選んだこと自体に順位向上の保証はありません。generateMetadataの公式資料
記事のタイトル、自己参照canonical、別言語URLを一件ずつ確かめます。例として日本語の個別記事が英語トップページをcanonicalにしていたら、言語切替リンクが正しくても別の問題です。直接アクセスとページ内遷移の両方でタイトルと本文を照合してください。
Server Actionも入力と権限の確認が必要
サーバーで動くことだけを理由に安全とは扱いません。処理内で入力を検証し、操作するユーザーにそのデータの更新権限があるか確認します。Next.jsのデータセキュリティ資料
| ケース | 期待する結果 |
|---|---|
| 未ログイン | 更新されない |
| 別ユーザーの対象ID | 認可で拒否される |
| 不正な入力 | 検証エラーで保存されない |
| 正しい入力 | 対象データだけ更新される |
| 同じ送信の繰り返し | 業務要件に沿って重複を扱う |
再現を小さくして戻しやすくする
問題のルートを一つ選び、追加したライブラリや表示を一度に全部変えず、一箇所ずつ戻します。変更前の差分を保存し、build、直接アクセス、画面遷移、送信の順で確認します。
旧記事で述べていた「OGPをあまり更新しない方がDiscoverで評価される」という推測は撤回します。表示・URL・権限の正しさを具体的に確認することと、検索サービスに掲載されることは分けて扱います。
確認した一次情報
主要な主張については、本文中にも対応する資料へのリンクを残しています。
- Server and Client Componentsnextjs.org · official-documentation · 確認: 2026-09-05
- generateMetadataの公式資料nextjs.org · official-documentation · 確認: 2026-09-05
- Next.jsのデータセキュリティ資料nextjs.org · official-documentation · 確認: 2026-09-05