Next.jsでbasePathを変更した時に必要な対応
導入
Next.jsでサイトをサブディレクトリで運用したい場合は、以下のように設定することで可能です。
const nextConfig = {
basePath: '/hoge',
}
export default nextConfig
ですが、その設定を
- Next.js側で自動で設定を反映してくれる部分
- 自前で修正しないといけない部分
があったので、共有としてまとめます。
Next.jsのバージョンは以下になります
"next": "14.2.24"
自動で設定が反映された部分
Link⭕️
リンクコンポーネントは、以下の記述のままで
自動で、/hoge/list
のようになってくれたので対応は不要でした。
import Link from 'next/link'
<Link href="/list">リスト一覧へ</Link>
router.push⭕️
useRouter
を使ったリダイレクトのパスも、
/hoge/list
に自動で飛んでくれました。
import { useRouter } from 'next/navigation'
const router = useRouter()
router.push('/list')
自前で修正しないといけない部分
Image❌
public
以下に置いた画像をimageタグを使用した画像は全部切れてしまいました。
こちらは個別での対応が必要になります。
import Image from 'next/image'
<Image src='/common/logo.png' alt='' width={100} height={40} />
Imageコンポーネントのラッパーコンポーネントを用意して、
そこにAPP_BASE_PATH
として定数化したサブディレクトリを追加することで
アプリ全体に変更を適用させました。
(今回はNext.jsのImageコンポーネント使いませんでした、癖が強くて苦手、、)
'use client'
import { twMerge } from 'tailwind-merge'
// constants
import { APP_BASE_PATH } from '@/constants'
export function Image({ src, alt = '', className = '', ...props }) {
return (
<img
{...props}
src={APP_BASE_PATH + src} // サブディレクトリを適用
alt={alt}
className={twMerge('inline-block', className)}
/>
)
}
location.href❌
リダイレクトに関しては、router.push
でほぼ賄えると思うのですが、
私の場合、ログアウト時のリダイレクトなどにこちらを使用しています。
というのも、TanStack Query
を使ったSPAの場合、ログアウト後の状態をリセットする処理が
ちょっと面倒というのもあり、location.href
を使えば簡単に状態を初期化出来るためです。
こちらも、こんな感じでラッパー関数を用意してあげましょう。
import { APP_BASE_PATH } from '@/constants'
export function hardRedirect(path) {
window.location.href = `${APP_BASE_PATH}${path}`
}
cssの背景画像❌
これが地味にめんどいやつです。。
tailwindcssでベタ書きしているやつはもう、個別に対応しました。
bg-[url("/hoge/icon/under-arrow-gray.svg")]
reactのUIライブラリ系のcss.moduleの中の画像パス❌
react-select
とかその辺ですね。css.module
でカスタマイズしているので
そこで画像を使っている場合は、個別で対応が必要です。
storybookで管理しているコンポーネントで画像使っている時❌
コンポーネント内で使っているImage
コンポーネントのパスをいじったので、
こちらで画像のリンク切れが起こります。nextConfig
の設定はstorybookとは無関係なので。
最初は絶望しましたが、こちらの設定でstorybook側にも画像のサブディレクトリ化が出来ました。
- staticDirs: ['../public'],
+ staticDirs: [
+ {
+ from: '../public',
+ to: '/hoge',
+ },
+ ],
番外編:プロキシの設定にはサブディレクトリを反映したくない
例えば、APIのプロキシの設定をしている時などに、今のままだとbasePath
が
rewrites
にも反映されてしまいます。
その場合は、個別にbasePath:false
をすることで、basePathの設定を除くことが出来ます。
/** @type {import('next').NextConfig} */
const nextConfig = {
basePath: '/hoge',
async rewrites() {
return [
{
source: `${process.env.NEXT_PUBLIC_API_URL}/:path*`,
destination: `${process.env.NEXT_PUBLIC_PROXY_DESTINATION_URL}/:path*`,
basePath: false, // これが必要
},
]
},
}
export default nextConfig
最後に
色々なアプリが混在しているプロジェクトではサブディレクトリ使う場面もありそうですよね。
「これ、もっと簡単に対応出来るよ」とか、ありましたら、教えて頂けるとありがたいです🙏
参考記事
Discussion