>Home

Next.jsでSPAをやる方法

Tags:
Created: 2021-10-14 12:16:19Updated: 2021-10-17 14:20:42

Next.jsでSPAはどうやるのかなと思って調べたのでメモっておきます。
こちらの記事が参考になりました。
Building a single-page application with Next.js and React Router

ポイントは以下になります。

  • SSRを回避してReactRouterを使う
  • RewritesでNext.jsのルーティングを制御する

1.ReactRouterをダイナミックインポートで読み込んでSSRを回避する

With no SSRに書いてあるようにダイナミックインポートでssrをfalseにして読み込むとCSRにできます。なので下記のようにReactRouterをダイナミックインポートで読みこむようにすればCSRでSPAができるようになります。

// ReactRouterのコンポーネント

const SpaRoot = () => {
	return (
		<BrowserRouter>
			<Switch>
				<Route exact path={"/"} component={Top} />
				<Route path={"/about"} component={About} />
			</Switch>
		</BrowserRouter>
	)
}

export default SpaRoot
// pages/index.tsx

export default function Home() {
	const DynamicComponentWithNoSSR = dynamic(() => import('./spaRoot'), { ssr: false })
	return (<DynamicComponentWithNoSSR />)
}

2.RewritesでNext.jsルーターを制御

ただしそれだけだとNext.jsのルーターの機能とReactRouterの機能が干渉しあって予期しない動作になってしまいます。例えば、物理的に「/」にしかページがない状態で、「/about」を開こうとするとNext.jsは物理的に異なるファイルのページ遷移を行うため404エラーになってしまいます。そこでRewritesを使ってNext.jsのルーターが常にルートページを読み込むように制御してやります。これでNext.jsのルーターとReactRouterの整合性が取れて期待通りの挙動になります。

// next.config.js

module.exports = {
	async rewrites() {
		return [
			{
				source: '/:any*',
				destination: '/',
			},
		]
	},
}

以上でNext.jsでSPAができるようになります。