【Nuxt.js】Nuxtでよく出るエラーと解決法まとめ

JavaScript

こんにちは、かつコーチです。

これまでNuxt.jsシリーズでは、ルーティングやデータ取得、サーバーAPIなど基本機能を一通り解説してきました。

ここからは少し毛色を変えて、実践Tips・つまずき解決編です。

今回は、Nuxtを触っていると本当によく出会うエラーを、原因と解決法のセットでまとめます。

エラーメッセージを見て固まってしまう前に、パターンを知っておけば対処のスピードがぐっと上がります。

Nuxtでエラーが出やすい場面

Nuxtのエラーは、大きく3つの場面で発生しやすい傾向があります。

1つ目は、モジュールのインストール漏れによる起動時エラーです。

2つ目は、SSRとCSRの結果が食い違うことで起きるhydration系エラーです。

3つ目は、開発サーバー起動時のポート競合など環境まわりのエラーです。

この3つを頭に入れておくと、エラーメッセージを見たときに「どのカテゴリの話か」がすぐに見えてきます。

よくあるエラーとBefore/Afterでの対処

エラー1: モジュール未インストールによる起動エラー

nuxt.config.tsmodulesを追加したのに、モジュール本体をインストールし忘れるとエラーになります。

[nuxt] Error: Cannot find module '@pinia/nuxt'
Require stack:
- /project/nuxt.config.ts

原因は単純で、設定ファイルに書いただけでモジュールが自動で入るわけではないことです。

// ❌ Before: nuxt.config.tsに書いただけでインストールしていない
export default defineNuxtConfig({
  modules: ["@pinia/nuxt"],
});
# ✅ After: モジュール本体を先にインストールする
npm install @pinia/nuxt pinia
// nuxt.config.tsはこのままでOK
export default defineNuxtConfig({
  modules: ["@pinia/nuxt"],
});

modules配列に名前を書く作業と、パッケージをインストールする作業はセットだと覚えておきましょう。

エラー2: Hydration mismatch(サーバーとクライアントの表示不一致)

サーバーで生成したHTMLと、ブラウザ側で再構築したHTMLが一致しないと出るエラーです。

[Vue warn]: Hydration node mismatch:
- rendered on server: <span>2026-08-22 10:30:00</span>
- expected on client: <span>2026-08-22 10:30:04</span>

原因の多くは、Date.now()Math.random()など、実行のたびに結果が変わる処理を描画中に呼んでいることです。

<!-- ❌ Before: サーバーとクライアントで結果が変わる -->
<script setup lang="ts">
const now = new Date().toLocaleString();
</script>

<template>
  <span>{{ now }}</span>
</template>
<!-- ✅ After: onMountedでクライアント側だけに反映する -->
<script setup lang="ts">
import { ref, onMounted } from "vue";

const now = ref<string | null>(null);

onMounted(() => {
  now.value = new Date().toLocaleString();
});
</script>

<template>
  <span>{{ now ?? "読み込み中..." }}</span>
</template>

私が初めてこのエラーに遭遇したときは、コンソールに赤い警告が出ているだけで画面自体は正常に見えたため、しばらく放置してしまいました。

ですが本番環境ではチラつきの原因になっていて、後から気づいて修正した経験があります。

[Vue warn]: Hydration node mismatchが出たら、時刻・乱数・window参照を疑うのが第一歩です。

エラー3: 開発サーバーのポート競合エラー

npm run devを実行したときに、ポートがすでに使われていて起動できないことがあります。

ERROR  Port 3000 is already in use

原因は、前回のNuxtプロセスが正常終了せずに残っていることがほとんどです。

# ❌ Before: エラーを無視して何度もdevを叩いてしまう
npm run dev
npm run dev
npm run dev
# ✅ After: ポートを使っているプロセスを特定して終了する
lsof -i :3000
kill -9 <表示されたPID>
npm run dev

もしくは、Nuxt側でポートを指定して起動する方法もあります。

# ✅ After(別解): 別ポートで起動する
npm run dev -- --port 3001

ターミナルを閉じずにCtrl+Cで正しく終了する癖をつけておくと、この問題自体を減らせます。

エラー4: useFetchのURLが相対パスで解決できないエラー

サーバーサイドの処理内で相対パスのAPIを呼ぶと、接続エラーになることがあります。

FetchError: [POST] "/api/posts": <no response> ECONNREFUSED

サーバーサイドで実行される処理は、ブラウザのようにホストを自動補完してくれません。

// ❌ Before: サーバーサイドで相対パスをそのまま使う
const { data } = await useFetch("/api/posts");
// ✅ After: server/api配下の内部呼び出しは相対パスのままでよいが、
// 外部APIを叩く場合は絶対URLで組み立てる
const config = useRuntimeConfig();
const { data } = await useFetch(`${config.public.apiBase}/posts`);

server/api/内のAPIを呼ぶだけなら相対パスで問題ありませんが、外部の別サーバーを叩く場合は絶対URLが必須です。

このあたりを混同すると、ローカルでは動くのに本番だけエラーになる、という状態にハマりやすいので注意してください。

応用:エラーを未然に防ぐ習慣

nuxi typecheckでビルド前に気づく

エラーの多くは、実行してから初めて気づくものです。

nuxi typecheckコマンドを使うと、TypeScriptの型エラーを事前に洗い出せます。

npx nuxi typecheck

CI(継続的インテグレーション)にこのコマンドを組み込んでおくと、本番反映前にミスを検知できます。

エラーメッセージは最初の1行だけでなく全体を読む

Nuxtのエラーは、原因の手がかりがスタックトレースの途中に埋もれていることがよくあります。

最初の1行だけで判断せず、atから始まる行を追ってどのファイル・どの処理で起きているかを確認する習慣をつけましょう。

まとめ

この記事のポイント

  • Nuxtのエラーは「モジュール未インストール」「hydration不一致」「環境まわり」の3系統に大別できる
  • modulesに書くだけでなくパッケージのインストールも忘れずに行う
  • hydrationエラーは時刻や乱数などサーバー・クライアントで結果が変わる処理が原因になりやすい
  • ポート競合はプロセスの終了漏れが原因のことが多い
  • 外部APIを呼ぶuseFetchは絶対URLで組み立てる

次に読むべき記事

次回は、useFetchがSSRとCSRで二重に実行されてしまうという、もう少し踏み込んだつまずき事例を紹介します。

タグ: #Nuxt.js #初心者向け #エラー解決

タイトルとURLをコピーしました