📝

Next.jsの15.5にて、Pages RouterでもTyped Routesを使う方法 

に公開

Next.js 15.5でPages RouterでもTyped Routesを使う方法

結論

  • next.config.jstypedRoutes: true を設定
  • tsconfig.jsoninclude".next/types/**/*.ts" を追加
  • Pages Routerでも <Link href="..."> は型安全になる
  • ただし router.pushnext/navigation 経由なら型が効くが、next/router 経由では効かない
  • 特定の箇所のみ型を当てたい場合は、import {type Route} from 'next'から読み込んで指定してあげればよい。

背景

Next.js 15.5から導入されたTyped Routesは、プロジェクト内のルート定義から .next/types/routes.d.ts を生成し、<Link href>router.push に与えるパスをコンパイル時(ビルド時)にチェックしてくれる機能です。

リリース当初、Typed RoutesはApp Routerでしか使えませんでした。ところが実務ではPages Routerでも使いたい場面があり調べてみたところ、公式のIssueで言及されていたPRで解決方法が公開されていました。手順通り設定したら、Pages Routerでも <Link> にTyped Routesを適用することができました!

https://github.com/vercel/next.js/issues/83010
https://github.com/vercel/next.js/pull/83029
https://github.com/vercel/next.js/pull/83031/files

セットアップ

1) next.config.jstypedRoutes: trueを追記

/** @type {import('next').NextConfig} */
const nextConfig = {
  typedRoutes: true,
};

module.exports = nextConfig;

2) ルートディレクトリのtsconfig.jsonのincludeに.next/types/**/*.tsを追記

  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    ".next/types/**/*.ts"
  ],

3) npm run buildの実行

ファイルへの追記が終われば、npm run buildを実行しビルドをしてみてください。正しく機能していれば、.next/types/に下記のようなファイルが生成されるはずです。

生成されたtypesディレクトリの例

コード例

正しい例

パスが存在している

import Link from "next/link";

export default function Home() {
  return (
    <nav>
      <Link href="/">Top</Link>
      <Link href="/about">About</Link>
      <Link href="/blog/hello-next">Blog detail</Link>
    </nav>
  );
}

ダメな例

パスが存在していない。(タイポしている)

<Link href="/foobar">Broken</Link> // 型エラー

Dynamic RoutesもOK

// /pages/blog/[slug].tsx がある前提
import { useRouter } from "next/navigation";

export default function Go() {
  const router = useRouter();
  router.push("/blog/typed-routes-works"); // OK
  router.push("/blog/"); // 型エラー(不足)
  router.push("/blog/unknown/extra"); // 型エラー(過剰)
  return null;
}

よくある躓き箇所

型エラーが表示されない

  • tsconfig.json に .next/types/**/*.ts を含め忘れている
  • エディタのTSサーバーが古いキャッシュを持っている(VS Code再起動)
  • Devサーバー未起動で .next/types/ がまだ生成されていない
  • 一度 next dev を再起動してみる
  • VS CodeのワークスペースTSを使っているか確認
  • ビルド(npm run build)してみる

補足

特定箇所で型を指定したい場合

import {type Route} from 'next'をし、型を指定してあげれば型が適用されます。

import { type Route } from 'next';

const myRoute: Route = '/blog/my-post';
// または
function navigateTo(path: Route) {
  // ...
}

Discussion