next.jsでSSRの問題が起きたときにはdynamicとssr:falseでお手頃SSR回避出来る

2 min読了の目安(約1200字TECH技術記事

next.jsは大変便利だが、SSRがデフォルト挙動になっているので、ちょこちょこwindowが無いとかで怒られがちになる。
そういう場合はdynamicを利用すれば良い

https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr

もともとdynamic importのための機能ではあるが、SSR回避にも使える。
だいたい上記公式ページにまとまっているが、ちょいちょい忘れるのでメモ

例示

ちょっと雑だが、こんな具合にwindowを利用しているようなコンポーネントがあったとする(SSR未対応な手頃な例示が見つからなかったので、行儀の良くない例示なのはご了承いただきたい)

// components/ClientOnlyComponent.js
window.SOME_GLOBAL_ITEM = "FOO" 
export const ClientOnlyComponent = () => {
  return <div>{window.SOME_GLOBAL_ITEM}</div>
}

これをそのまま読み込むと

ReferenceError: window is not defined

のようなエラーが出る。そこで上記のdynamicを利用する。

// pages/index.js

import dynamic from "next/dynamic"
const AvoidSSRComponent = dynamic(
  () => import('../components/ClientOnlyComponent')
    .then(modules =>  modules.ClientOnlyComponent), 
  {ssr: false}
)

export default function Home() {
  return (
    <div>
      <AvoidSSRComponent/>
    </div>
  )
}

default exportにしていれば() => import('../components/ClientOnlyComponent')だけで済むが、今回はnamed exportにしたのでthen(modules => ...)としている。
第二引数に{ssr:false}をつけるのがポイントだ。

また、components/ClientOnlyComponent.jspagesディレクトリ下に置いてしまうと、ページ対象としてコンパイルされてbuild時のみコケたりするので注意(next devでやってるとコケないのでたまに気づかない)