LoginSignup
12
11

More than 3 years have passed since last update.

Next.jsで「document is not defined」と怒られたときの対処法

Posted at

Next.jsを使っていると様々なエラーに遭遇します。その中でも

  • document is not defined
  • window is not defined

これらのエラーは良く見るので対処方法を解説します。
エラー画面は以下のようなものです。
WS000006.JPG

documentの未定義エラーの対処方法

「document is not defined」の対処方法は2つあります。

1.documentの定義判定

1つ目はグローバル変数にdocumentがあるのかの存在判定です。
documentが定義されている場合のみプログラムを実行するのでif (typeof document !== 'undefined') {}でくくります。今回のプログラムではdocumentオブジェクトを使って、クッキーに値をセットしています。

index.jsx
export default function Index() {
  //document変数が定義されているときのみ
  if (typeof document !== 'undefined') {
    //クッキーに値をセット
    document.cookie = "クッキー";
  }

  return (
    <div style={{textAlign: "center", marginTop: "50px"}}>
      {/* 値の表示 */}
      <h1>値:{typeof document !== 'undefined'?document.cookie:""}</h1>
    </div>
  )
}

WS000001.JPG

2.ブラウザ実行判定

2つ目の方法はブラウザで動いているかの判定です。ブラウザで動いているときのみ、documentを使った処理を実行します。process.browserがtrueの場合はブラウザで動いている証拠です。一方、undefinedの場合はサーバーでの実行になります。

index.jsx
export default function Index() {
  //ブラウザ実行時のみ
  if (process.browser) {
    //クッキーに値をセット
    document.cookie = "クッキー";
  }

  return (
    <div style={{textAlign: "center", marginTop: "50px"}}>
      {/* 値の表示 */}
      <h1>値:{process.browser?document.cookie:""}</h1>
    </div>
  )
}

なぜ「documentが定義されていない!」と怒られるのか?

なぜdocumentwindowが定義されていないと怒られているのかというと、サーバーサイドでブラウザ用のグローバル変数を使おうとしているためです。

Next.jsはサーバーサイド、クライアントサイド両方で動くフレームワーク。そのため、定義したソースはサーバー、ブラウザ両方の環境で実行されます。

そして、documentwindowはクライアントだけで定義されているグローバル変数です。サーバー環境で動かそうとすると「そんなグローバル変数は定義されていない!」とエラーが発生します。

なので、if (process.browser)でブラウザのみの判定を入れればサーバー環境での実行時には無視され、クライアント環境だけで動くのです。

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11