🕌
Nuxt3で`window is not defined` または `document is not defined`の原因と対処
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