結構こういう要求はあるとおもいます。
解決する課題
/static
へのリンクが途切れる<Link>
で遷移するとbasepathが変わる
つまり、サブディレクトリ以下でNext.jsを使ったSPAをしたい!!という人向けの記事です。
/static
へのリンクをサブディレクトリ以下になるようにする
たとえばexample.com/next-app
でデプロイしたいとき、example.com/next-app/_next/static
以下にJSファイルなどは置かれます。しかし、なにも設定しないままだとNext.jsではexample.com/_next/static
へのリンクを張るため404となってしまいます。
これを解決するには、next.config.jsでassetPrefixを設定する必要があります。
const isProd = process.env.NODE_ENV == 'production'; const url = isProd ? 'https://example.com/next-app' : ''; module.exports = { assetPrefix: url, }
これでローカルでも本番環境でも/static
へアクセスできるようになります。
<Link>
で遷移するとbasepathが変わる
上の方法で/static
へアクセスできるようになりました。しかし、実はルーティングをしている場合これだけでは対応が不十分です。
たとえば以下のような<Nav>
を考えます。
import * as React from 'react'; import Link from 'next/link'; const Nav = () => ( <nav> <ul> <li><Link href="/"><a>Top</a></Link></li> <li><Link href="/about"><a>About</a></Link></li> <li><Link href="/content"><a>Content</a></Link></li> </ul> </nav> );
このNav要素はローカル環境ではなんの問題もなく動作します。しかし、本番環境ではうまく動作してくれません。たとえば本番環境でAboutをクリックすると、example.com/about
へとURLが変わります。もうおわかりですね。この状態でリロードするとページが読み込まれません。
この問題の解消方法はとても簡単です。as
属性をつけてあげるだけです。
<Link href="/about" as="/next-app/about"><a>About</a></Link>
しかし、今度はローカルでうまく動作しません。困りましたね。
設定で切り替える
参考: Deploy your NextJS Application on a different base path (i.e. not root)
どうやらNext.jsにはnext.config.jsから値を取ってくる機能があるようです。
import getConfig from 'next/config'; const {publicRuntimeConfig} = getConfig();
こうするとnext.config.jsで設定したpublicRuntimeConfigの値を取ってこられるようになります。あとはこれを設定して、Linkのasでこれを使った設定をしてやれば完成です。詳しいコードはこちらを参考にしてください。