Nuxt.jsでSSR開発中に「window is not defined」というエラーでハマったので備忘録として残します。
この記事でわかること:
- 「window is not defined」エラーが発生する根本原因
- SSR(サーバーサイドレンダリング)環境でのブラウザAPIの扱い方
- process.clientを使用した具体的な解決コード
目次
[現象] ブラウザのAPIを叩くと発生する参照エラー
Nuxt.jsやVue.jsのSSR(サーバーサイドレンダリング)モード、あるいはSSG(静的サイト生成)モードを使用している際、実行時に以下のエラーが発生し、動作が停止することがあります。
ReferenceError: window is not defined[環境] 使用技術
| フレームワーク | Nuxt.js / Vue.js |
| レンダリング | SSR(サーバーサイドレンダリング)/ SSG(静的サイト生成) |
| エラー発生箇所 | mounted / created ライフサイクルフックやプラグイン内 |
[原因] サーバーサイドにはwindowオブジェクトが存在しない
Nuxt.jsのSSR/SSGモードでは、ページがブラウザに表示される前に、サーバー(Node.js環境)で一度JavaScriptが実行され、HTMLが生成されます。
サーバーサイド環境(Node.js)には、ブラウザ固有のオブジェクトである window や document が存在しません。 そのため、コンポーネントの初期化時にこれらにアクセスしようとすると、サーバーサイドでのレンダリング中にエラーが投げられてしまうのです。特に、mounted 内であってもサーバーサイドレンダリングの一環として評価されるタイミングがある場合に注意が必要です。
[解決策] process.clientによる実行制御
この問題を解決するには、該当のコードが「クライアントサイド(ブラウザ)」でのみ実行されるように、条件分岐を追加します。
修正前のコード(エラーが発生する例):
export default {
mounted() {
// サーバーサイドでも実行されるため、windowが見つからずエラーになる
window.addEventListener('resize', this.handleResize);
},
methods: {
handleResize() {
console.log('Window resized!');
}
}
}修正後のコード:
export default {
mounted() {
// クライアントサイドでのみ実行されるように制御
if (process.client) {
window.addEventListener('resize', this.handleResize);
}
},
methods: {
handleResize() {
console.log('Window resized!');
}
}
}解説:
Nuxt.jsでは、実行環境を判定するための process.client 変数が用意されています(Nuxt 2では process.browser も利用可能)。この条件分岐を加えることで、サーバーサイドでのレンダリング時は window へのアクセスをスキップし、ブラウザに読み込まれた後だけ安全にイベントリスナーを登録できます。
[まとめ]
- エラー原因: SSR環境のサーバー側(Node.js)には
windowオブジェクトがないため。 - 対策:
process.clientを使って、ブラウザ環境のみで動くように制御する。 - コツ: 外部のJSライブラリを使用する場合も、
ssr: false設定や同様の条件分岐を検討しましょう。
これでSSR/SSG特有の参照エラーを回避できるようになります!

