Next.js 15 から 16 へのアップデートで遭遇した問題と対処法をまとめてみた

Next.js 15 から 16 へのアップデートで遭遇した問題と対処法をまとめてみた

2026.01.29

はじめに

先日Next.js 15から16へのプロジェクトのアップデートを行いました。
その過程でいくつかの問題に遭遇したため、それらの問題と対処法を共有します。

特にParallel RoutesやIntercepting Routesを使用しているプロジェクトでは、型チェックの厳密化により複数のエラーが発生する可能性があります。

あくまで私の環境で出た問題と、それに対する対処法になります。

環境情報

  • Next.js: 15.4.x → 16.1.x
  • TypeScript: 5.9.x
  • React: 19.x

発生した問題と対処法

1. middleware → proxy への変更

Next.js 16 では、middleware.ts というファイル名が非推奨になり、proxy.ts に変更されました。

エラーメッセージ

ビルド時に以下の警告が表示されます:

⚠ The "middleware" file convention is deprecated. Please use "proxy" instead.
Learn more: https://nextjs.org/docs/messages/middleware-to-proxy

対処法

  1. ファイル名を middleware.tsproxy.ts に変更
  2. エクスポートする関数名を middlewareproxy に変更
// Before: src/middleware.ts
export function middleware(request: NextRequest) {
  // ...
}

// After: src/proxy.ts
export function proxy(request: NextRequest) {
  // ...
}

config オブジェクトの形式は変更不要です:

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}

注意: proxy.ts は Node.js ランタイムでのみ動作し、Edge Runtime はサポートされていません。Edge Runtime を使用している場合は、middleware.ts を維持する必要があります。

2. Parallel Routesの型チェック厳密化

Next.js 16 では、Layout コンポーネントの Props 型がディレクトリ構造に基づいて厳密にチェックされるようになりました。

エラーメッセージ

Type error: Type 'typeof import(".../[id]/layout")' does not satisfy the constraint 'LayoutConfig<"/[lang]/products/[id]">'.
  Types of property 'default' are incompatible.
    Property 'modals' is missing in type 'LayoutProps<"/[lang]/products/[id]">' but required in type '{ tabs: ReactNode; modals: ReactNode; }'.

原因

Layout コンポーネントで modals という Parallel Route スロットを受け取っているにもかかわらず、対応する @modals ディレクトリ(または default.tsx)が存在しない場合に発生します。

対処法

該当する Parallel Route ディレクトリに default.tsx を追加します:

app/
└── [lang]/
    └── products/
        └── [id]/
            ├── layout.tsx      # modals を受け取る
            ├── page.tsx
            ├── @tabs/
            │   └── ...
            └── @modals/        # 追加
                └── default.tsx # 追加

default.tsx の内容:

// app/[lang]/products/[id]/@modals/default.tsx
const Default = () => null

export default Default

Parallel Route の default.tsx は、そのスロットがアクティブでない場合にレンダリングされるフォールバックコンポーネントです。null を返すことで、何も表示しないようにできます。


3. Layout と Page の Props 型分離

Next.js 16 では、Layout コンポーネントと Page コンポーネントで受け取る Props が厳密に区別されるようになりました。

エラーメッセージ

Property 'searchParams' is missing in type 'LayoutProps<"/[lang]/products/[id]">' but required in type 'ProductDetailPageProps'.

原因

Layout コンポーネントは searchParams を受け取りませんが、Page 用の Props 型を Layout で使用していた場合にエラーが発生します。

対処法

Layout 専用の型を定義し、Page の型と分離します:

// Before: Layout と Page で同じ型を使用
type ProductDetailPageProps = {
  params: Promise<{ lang: string; id: string }>
  searchParams: Promise<{ tab?: string }>
  children: ReactNode
}

export default async function ProductDetailLayout({
  params,
  searchParams,  // Layout では使えない
  children,
}: ProductDetailPageProps) {
  // ...
}
// After: Layout 専用の型を定義
type ProductDetailLayoutProps = {
  params: Promise<{ lang: string; id: string }>
  tabs: ReactNode
  modals: ReactNode
  children: ReactNode
}

type ProductDetailPageProps = {
  params: Promise<{ lang: string; id: string }>
  searchParams: Promise<{ tab?: string }>
}

export default async function ProductDetailLayout({
  params,
  tabs,
  modals,
  children,
}: ProductDetailLayoutProps) {
  // ...
}

export default async function ProductDetailPage({
  params,
  searchParams,
}: ProductDetailPageProps) {
  // ...
}

4. Intercepting Routes + Parallel Routes の型問題

Intercepting Routes 内で Parallel Routes を使用している場合、Next.js 16 のビルド時に自動生成される型定義ファイル(.next/types/)が正しく型を解釈できないことがあります。

エラーメッセージ

.next/types/validator.ts(xxx,xx): error TS2344:
Type 'typeof import(".../(..)(..)items/[itemId]/layout")' does not satisfy
the constraint 'LayoutConfig<"/[lang]/items/[itemId]">'.
  Property 'pages' is missing in type 'LayoutProps<"/[lang]/items/[itemId]">'

原因

Intercepting Routes((..)(..)(..) など)内で Parallel Routes(@pages など)を使用している場合、Next.js の自動生成される型定義が Intercepting Routes を元のルートとして解釈してしまい、型の不整合が発生します。

例えば、以下のようなディレクトリ構造の場合:

app/
└── [lang]/
    └── products/
        └── [id]/
            └── @modals/
                └── (..)(..)items/    # items を intercept
                    └── [itemId]/
                        ├── layout.tsx  # @pages を使用
                        └── @pages/
                            └── default.tsx

この layout.tsx/[lang]/products/[id]/@modals/(..)(..)items/[itemId] に存在しますが、型チェックでは /[lang]/items/[itemId] の型として検証されてしまいます。

対処法

tsconfig.json.next/types/validator.ts を除外します:

{
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    ".next/types/**/*.ts",
    ".next/dev/types/**/*.ts"
  ],
  "exclude": [
    "node_modules",
    ".next/types/validator.ts"
  ]
}

注意: この方法は型チェックの一部を無効化するため、本来検出されるべきエラーが見逃される可能性があります。一部のケースにおける暫定的な対処法としてご検討ください。


まとめ

Next.js 15 から 16 へのアップデートで遭遇した主な問題は以下の通りです:

問題 対処法
middleware → proxy ファイル名・関数名を変更
Parallel Routes の型チェック @xxx/default.tsx を追加
Layout/Page の Props 分離 Layout 専用の型を定義
Intercepting Routes + Parallel Routes validator.ts を exclude

特に Parallel Routes や Intercepting Routes を多用しているプロジェクト では、型チェックの厳密化により複数のエラーが発生する可能性があります。アップデート前にこれらの点を確認しておくことをお勧めします。

参考リンク

この記事をシェアする

FacebookHatena blogX

関連記事