大前提として、nuxtServerInitというAction名のとおり、これはサーバサイドでしか実行されない。
静的サイトモードだと、設定によるけどgenerateコマンドの実行時に呼ばれる。
そしてfallbackのSPAモード。これは動的に扱いたいroute用の機能だけど、このSPAモード用のhtml(200.htmlとか404.htmlとか)の生成時にはnuxtServerInitは呼ばれない。
SPAモードではnuxtServerInit呼ばれない、という仕様なんだから確かにそのとおり。なんだけどこれを完全に失念しててSPAモードで表示していた一部ページと、そこから遷移した各ページで一部データにアクセスできない、という状況が生まれてしまっていた。
解決する方法はいくつかあるけど、今回はSPAモードでもnuxtServerInitを呼ぶ方法を採用した。
実装は簡単。
まずはStateに初期化済みかどうか判定できる値を用意する。initialized: booleanみたいな値を用意するのでもいいだろう。
次にpluginを追加する。単純に、Stateが初期化済みでなければnuxtServerInitを実行する。resとかreqとかcontextの一部の値はクライアント側ではアクセスできないので、そこは注意が必要。
// ~/plugins/init.client.ts
import { Context } from '@nuxt/types'
import { RootState } from '~/store'
export default async function ({ app, store }: Context): Promise<void> {
if (!(store.state as RootState).initialized) {
await store.dispatch('nuxtServerInit', app.context)
}
}nuxt.config.tsのplugin設定はこんな感じに
plugins: [
...,
{ src: '~/plugins/init.client.ts', mode: 'client' },
]mode: 'client'が重要。nuxtServerInitはサーバサイドでは普通に呼ばれるので、SPAモード(=ブラウザ側)でのみ処理されればいい。