Skip to content

fix(scaffold): Google Fonts URL内の & が & に変換される問題を修正#900

Open
teppei-d wants to merge 1 commit into
d-zero-dev:devfrom
teppei-d:fix/scaffold-restore-ampersand-in-google-fonts-url
Open

fix(scaffold): Google Fonts URL内の & が & に変換される問題を修正#900
teppei-d wants to merge 1 commit into
d-zero-dev:devfrom
teppei-d:fix/scaffold-restore-ampersand-in-google-fonts-url

Conversation

@teppei-d
Copy link
Copy Markdown
Collaborator

問題

本番環境でWebフォント(Google Fonts)が適用されない現象が発生していた。

原因

2段階の問題が絡んでいた。

① JSDOM による & 変換

pageCompiler のビルドプロセスでは、PugテンプレートのコンパイルにJSDOMを使用している。JSDOMがHTMLをシリアライズする際、属性値内の & を仕様に従い & にエスケープする。

その結果、Google Fonts の <link> タグが以下のように変換される。

変換前(Pugソース)

<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap" rel="stylesheet">

変換後(ビルド出力)

<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&amp;display=swap" rel="stylesheet">

② Cloudflare Fonts の挙動

Cloudflare Fonts が有効なプロジェクトでは、Google Fonts の <link> 要素が自動的に <style>@font-face)にインライン展開される。この変換処理が &amp; を正しく解釈できず、URLが破損してフォントが読み込めなくなっていた。& であれば正常に処理される。

手動で &amp;& に書き換えたところ、フォントが正常に反映されることを確認している。

対応

pageCompilerreplace オプション(JSDOMシリアライズ・Prettier・minifier 処理が完了した後に実行される最終テキスト変換フック)を使用し、fonts.googleapis.com および fonts.gstatic.comhref 属性内に限定して &amp;& に戻す処理を追加した。

replace: (content) => {
  // JSDOMが &amp; に変換した Google Fonts URL の & を元に戻す
  return content.replaceAll(
    /href="(https:\/\/fonts\.(?:googleapis|gstatic)\.com[^"]*)"/g,
    (_, url) => `href="${url.replaceAll('&amp;', '&')}"`,
  );
},

正規表現を fonts.googleapis.com / fonts.gstatic.comhref 属性内に限定することで、他の要素の &amp; には影響しない。replaceAll により、URL内に &amp; が複数ある場合も全て処理される。

テストについて

このスキャフォールドにテストコードは追加していない。replace 関数は純粋な文字列変換だが、このリポジトリから生成される案件リポジトリにテストコードが含まれることになりノイズになるため、意図的に追加しない方針としている。

動作確認は案件リポジトリのビルド出力(htdocs/ のHTMLファイル)で、Google Fonts の <link> 要素の href 属性内が &amp; ではなく & で出力されることを確認済み。

…SDOM

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant