プロジェクト作成

create-next-app コマンドで作成する。

パッケージマネージャに pnpm を使用。選択肢は全てデフォルト。

$ pnpx create-next-app@latest --use-pnpm example-nextjs

✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like your code inside a `src/` directory? … No
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to use Turbopack for `next dev`? … Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No

.node-version ファイルを作成する:

# .node-version を作成
$ node -v > .node-version

# もしくは major version のみ記載する場合
$ node -p 'process.versions.node.split(".")[0]' > .node-version

依存パッケージを追加

パッケージをいくつか追加する。

2025-11-16 追記: Tailwind CSS v4 サポートを謳う eslint-plugin-better-tailwindcss を追加

# dependencies
$ pnpm add tailwind-variants next-intl

# devDependencies
$ pnpm add -D \
    prettier \
    eslint-config-prettier \
    @trivago/prettier-plugin-sort-imports \
    prettier-plugin-classnames \
    prettier-plugin-merge \
    prettier-plugin-tailwindcss \
    eslint-plugin-better-tailwindcss

ESLint 設定

prettier と TypeScript の未使用変数に関する設定を追加。

+// @ts-check
 import nextVitals from "eslint-config-next/core-web-vitals";
 import nextTs from "eslint-config-next/typescript";
+import eslintConfigPrettier from "eslint-config-prettier";
+import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss";
 import { defineConfig, globalIgnores } from "eslint/config";

 const eslintConfig = defineConfig([
   ...nextVitals,
@@ -13,6 +16,30 @@ const eslintConfig = defineConfig([
     "build/**",
     "next-env.d.ts",
   ]),
+  eslintConfigPrettier,
+  {
+    rules: {
+      "@typescript-eslint/no-unused-vars": [
+        "warn",
+        { argsIgnorePattern: "^_" },
+      ],
+    },
+  },
+  {
+    plugins: {
+      "better-tailwindcss": eslintPluginBetterTailwindcss,
+    },
+    settings: {
+      "better-tailwindcss": {
+        entryPoint: "app/globals.css",
+      },
+    },
+    rules: {
+      ...eslintPluginBetterTailwindcss.configs["recommended-warn"].rules,
+      "better-tailwindcss/enforce-consistent-line-wrapping": "off",
+      "better-tailwindcss/enforce-consistent-class-order": "off",
+    },
+  },
 ]);

 export default eslintConfig;

2025-11-16 追記: 設定について

  • no-unused-vars はエラーでなく warn レベルになるようにする
    • コーディング中にエディタ上でエラーが即座に報告されるのが煩わしいため
    • warn レベルの問題を CI で検出する想定
  • eslint-plugin-better-tailwindcss
    • entryPoint で create-next-app で作られるグローバル CSS ファイルを指定
    • recommended ルールを warn レベルで取り込む
    • 改行と順序のルールは off にし、 Prettier に任せる

Prettier 設定

import のソート、 Tailwind CSS のクラス名のソートと改行を行うプラグインを有効化。

.prettierrc を作成:

{
  "plugins": [
    "@trivago/prettier-plugin-sort-imports",
    "prettier-plugin-tailwindcss",
    "prettier-plugin-classnames",
    "prettier-plugin-merge"
  ],
  "importOrder": ["<THIRD_PARTY_MODULES>", "^@/", "^[./]"],
  "tailwindFunctions": ["tv"],
  "customFunctions": ["tv"]
}

なお tailwindFunctionsprettier-plugin-tailwindcss の設定で、 customFunctionsprettier-plugin-classnames の設定。

2025-11-16 追記: prettier-plugin-classnames 関連の変更

ignore リストに pnpm の lockfile を入れておく。

$ echo pnpm-lock.yaml >> .prettierignore

package.json のスクリプト定義に "format": "prettier --write ." を追加し、コマンド実行してフォーマットを適用しておく。

$ pnpm run format

next-intl 設定

ドキュメントの通り設定する。 以下は locale-based routing と呼ばれる https://example.com/ja のようにパスに言語コードが入る設定。

App Router setup with i18n routing – Internationalization (i18n) for Next.js

  • messages/ja.jsonmessages/en.json を作成
  • next.config.ts を変更
  • i18n/navigation.ts を作成
  • i18n/request.ts を作成
  • middleware.ts を作成
  • i18n/routing.ts を作成
  • app/layout.tsxapp/[locale]/layout.tsx に移動、修正
  • app/page.tsxapp/[locale]/page.tsx に移動、修正

追加で TypeScript 型定義の設定を行う。

TypeScript augmentation – Internationalization (i18n) for Next.js

global.d.ts を作成:

import { routing } from "@/i18n/routing";
import messages from "@/messages/ja.json";

declare module "next-intl" {
  interface AppConfig {
    Locale: (typeof routing.locales)[number];
    Messages: typeof messages;
  }
}

開発サーバを起動し、ブラウザで http://localhost:3000 を開く。

http://localhost:3000/ja にリダイレクトされてページが表示されれば OK。