概要

Nuxt 3/4 + Nuxt Content の環境で trailingSlash: "append" を設定している場合、コンテンツ内のPDFや画像などの静的ファイルへのリンクが404エラーになることがあります。

発生条件

以下の条件がすべて揃った場合に発生します:

  1. Nuxt 3/4 + Nuxt Content を使用
  2. nuxt.config.tstrailingSlash: "append" を設定
  3. Markdownやコンテンツ内に静的ファイル(PDF、画像など)へのリンクがある

問題の詳細

症状

コンテンツ内で以下のようなリンクを記述した場合:

<ahref="/uploads/document.pdf"></a>

生成されるHTMLでは、リンクが以下のように変換されてしまいます:

/uploads/document.pdf/

末尾に / が追加されるため、静的ファイルにアクセスできず404エラーになります。

原因

Nuxt Content では、Markdown内の <a> タグは ProseA コンポーネントに変換されます。

デフォルトの ProseA コンポーネント(@nuxtjs/mdc パッケージ内)は以下のような実装になっています:

<t/e<tmN/epu<NmlxsupatlxltLotaeitLt>niekn>k:>href="props.href":target="props.target">

NuxtLink を使用しているため、nuxt.config.tstrailingSlash 設定の影響を受けます。

e}x)pe};nox,urpd}xtee,trfn}.diau,cemuxtofeltrnantLafutsiiila:nlgtlki.:{:ntdgse{{SfliansehN:ux"taCpopnefnidg"(,{

解決策

カスタムの ProseA コンポーネントを作成し、静的ファイルへのリンクの場合は通常の <a> タグを使用するようにします。

実装

components/content/ProseA.vue を作成:

<<c}ccc]c}c}t/so)ooo;o)o)/e<<tcnh}t};nnn""""""""""""""""ncr;nci}i}r;sma/N/ersr,a,sss................soesffecp<au<Nmitetdrtdrtttpjjpgwszddxxppcttnttnrrtrls>xsuppfyegyeedppnievioollppsxsus(e(euia-ltlxltp:pfepfqcbsfgegfbgpccssttvtitrrththtrptioLotareateauoat""g""p"""x"x"x""snerurunteftitLtso{:u::uinsa,,",,",,,",",",,Shsherer>>=nieepllrfet,,,,,trsorfnfnh"kn>tsSt{SteiUiaetle..rikut:t:dgRctfavfshsbes>p=rr:LFitetrtafS-i"iu=ic=id=ae/as;teldn"nnf=lFcHrfrealaeg,gdaueipFrpbt;tUtsnf,,elscElrierassRiegifseoxeolfosWWLc=nieRntpepeiiF:"en,ufe=sE=sUtt+ihtPenin.x.RhbhlrsrdtgschtchL(a(hee"o,i.ioreor"s"r"f>pmaomenmehe/e=sepnpfspftU"f:"(Cpsu.iu;tR);hp{o.ttotpL)rrnb=eone"eofadLsd){fpis[(o.(=sge(ws(".(U)eo)rh)Rrmer;L=Ce=hse>a(>rofs(el"{ee{fv(x.e:")tsdt";)tHa;arr=reg>tfes"thW=ri:"ettpfhar.(roebgpnaesdst.se=tWU"aiRprtLrgh)oe()ptes"x{.>tt)a)r;get">

ポイント

  1. 静的ファイルの判定 : ファイル拡張子で静的ファイルかどうかを判定
  2. 通常の<a> タグを使用: 静的ファイルの場合は NuxtLink ではなく通常の <a> タグを使用することで、trailingSlash 設定の影響を回避
  3. baseURLの追加 : NuxtLink を使わない場合、baseURLが自動適用されないため、手動で追加

動作確認

ビルド後、生成されたHTMLを確認:

ngprmeprung'ehnreerfa=t"e[^"]*\.pdf[^"]*"'output/public/path/to/page/index.html

期待する出力(末尾に / がない):

href="/base-url/uploads/document.pdf"

補足

なぜ trailingSlash: “append” を使うのか

  • SEOの観点から、URLの末尾の / の有無を統一することが推奨される
  • /page/page/ が別のURLとして扱われる(重複コンテンツ問題)のを防ぐ
  • 多くのサイトでは append(末尾に / を追加)を採用

他の解決策

  1. 絶対URLを使用 : コンテンツ内で https://example.com/uploads/document.pdf のように絶対URLを記述する(ただし、環境ごとにURLが異なる場合は管理が煩雑)

  2. trailingSlash設定を削除 : サイト全体の設定を変更する(他のページへの影響を考慮する必要あり)

環境

  • Nuxt 4.x(Nuxt 3.xでも同様の問題が発生する可能性あり)
  • Nuxt Content v3
  • @nuxtjs/mdc

参考