🕌

Nuxt3で`window is not defined` または `document is not defined`の原因と対処

2022/03/21に公開

NuxtChildを使ったテンプレートを作っているときに、idがない状態ではページリロードする必要があった。
内容としては以下のような感じ

<script setup lang="ts">
const route = useRouter()
const id = route.params.id

if(!id){
    location.reload()  // <-問題箇所
}
<script>

<template>・・・</template>

ところが、この状態だとdocument is not definedとなってしまう。

原因(推測)

location.reload()は、正確にはwindow.document.location.reload()である。
(windowとdocumentの記述が省略されている)

windowクラスやdocumentはDOMが生成された後にしか存在しない。
つまり、setupの状態ではまだDOMが生成されておらず、この状態でdocumentクラスを用いようとしてもundefinedとなる。

対処法

onMountedでdocumentクラスが生成された後に実行する

<script setup lang="ts">
const route = useRouter()
const id = route.params.id

onMounted(()=>{
    if(!id){
        location.reload()  // <-問題箇所
    }
})
<script>

<template>・・・</template>

documentが必要なライブラリインポートへの対処

TailwindCSSのライブラリであるFlowbiteを使った時も、document is not definedとなった。

<script setup lang="ts">
import 'flowbite'
<script>

<template>・・・</template>

これも同様にonMounted()の後にインポートすると解決できる。

<script setup lang="ts">
onMounted(()=>{
    import('flowbite');
})
</script>

process.brouser

DOMが生成されたかどうかをチェックするために、process.brouserで判別できる

<script>
if (!process.browser) {
  console.log('DOM生成されてません')
}else{
  console.log('DOM生成されてません')
}
</script>

Discussion