- PHPエンジニア
- アカウント(IT営業)
- SRE
- 他1件の職種
- 開発
- ビジネス
スタジオ・アルカナのマークアップエンジニアの野間です。
今年度は Next.js のSSG案件に何度か関わりました。その中でサブディレクトリにデプロイする案件で /public/ ディレクトリに置いている画像の読み込みで一工夫必要だったので、それについて書こうと思います。
そもそも /public/ を主な画像置き場として使わない方もいらっしゃると思いますが、静的サイトを主に作る方は私と同じようなことをするのではと思いこの記事を書きました。参考になりそうと思っていただける方は読み進めていただければと思います。
結論、相対パスでimport
いきなり結論ですが、相対パスでimportするのが一番シンプルでソースもキレイです。シンプルと言えばミスチルのSimpleって曲を知っていますか?いい曲なんですよ。おっと年齢がバレそうだ…。
相対パスでimportしようと思い立った経緯
ミスチルはさておき、サブディレクトリにデプロイする時は next.config.ts にてproductionビルドの時に使う basePath を指定すると、リンクやパスなど自動でうまいこと直してくれるのですが、例外があって /public/ からルートパスで読み込んでいるリソースのパスは直してもらえません。
そこで next.config.ts にて Public Runtime Config で設定したサブディレクトリの値を各ファイルで呼び出してパスの先頭に付けて、みたいなことをやった案件もあったのですが、最近のバージョンでは Runtime Config は 非推奨です。
next.config.js Options: Runtime Config | Next.js https://nextjs.org/docs/15/pages/api-reference/config/next-config-js/runtime-configuration
さてどうしたものかと調べてみたらenvファイルに設定する形で似たようなことをしている開発者の方の記事も見つけて試してみようと思ったのですが、ファイル毎に似たような記述を何度も書くことを考えると、面倒で重い腰が上がらない。だからと言って Image コンポーネントを自分でカスタマイズするほどフレームワークへの理解も深くない。その時ふと思いついたのです。「相対パスで /public/ の中のファイルを import したらいいのでは?」と。そしてやってみたらできたというわけです。
具体的な方法
ソースを交えつつ具体的な方法をご紹介していきます。 使用したNext.jsのバージョンは15.5.5、App Router です。
next.config.ts
まず、next.config.ts にて定数 basePath を定義して、値に productionビルドの時にサブディレクトリが入るようにします。そしてその定数 basePath を nextConfig の basePath として設定します。 ※該当箇所以外の要素や値は一例です。各環境に合わせて変更してください。
Imageコンポーネントのパス
Imageコンポーネントのsrc属性のパスは以下のようになります。Imageコンポーネントを使わずimg要素を使う場合も同じです。 ※該当箇所以外の要素や値は一例です。各環境に合わせて変更してください。
背景画像のパス
CSSは Tailwind.css をよく使うのですが、サブディレクトリデプロイ時の背景画像のパスは悩みどころです。今のところキレイな解決策が見つからず以下のような形を取っています。良い方法をご存知の方いらっしゃったら教えてください! ※該当箇所以外の要素や値は一例です。各環境に合わせて変更してください。
og:imageのパス
og:imageについては今回の趣旨とはずれて、相対パスでもルートパスでもあまり関係がないのですが、気をつけるべき点を見つけたので共有します。
サブディレクトリにデプロイする時も metadataBase はサブディレクトリなしで指定しないと、パスが https://ドメイン/サブディレクトリ/サブディレクトリ/opengraph-image.png みたいな感じにサブディレクトリが2つ連なる形で出力されて表示されなくなってしまいます。layout.tsx に以下のようにサブディレクトリ無しのurlを metadataBase に指定します。
最後に
さて、いかがだったでしょうか。Next.js のプロジェクトをサブディレクトリにデプロイする際の一助になれば幸いです!