Prompt
Reactで直接scriptタグを書かなければならない状況は存在する?
結論から言うと、React(Next.js)を使っていても 「直接 <script> タグを(あるいはそれに準ずる形で)書かなければならない状況」 は確実に存在するよ!
React のエコシステム内で完結するのが理想だけど、現実の開発では「React の外側」にある世界と通信しなきゃいけない場面があるんだ。還元主義的に、その「避けられない状況」を 4 つに分類して解剖してみよう。
1. 外部サービスのインテグレーション(サードパーティ)
これが最も多いケースだね。npm パッケージとして提供されていない、あるいはグローバルな窓口を必要とするサービスを導入する場合だ。
-
Google Analytics / GTM: ページの最上部で初期化コードを走らせる必要がある。
-
広告(AdSense): 特定の場所に広告ユニットのスクリプトを差し込む必要がある。
-
チャットボット(Zendesk, Intercomなど): ページ読み込み時にウィジェットを起動させるためのスクリプト。
これらは window オブジェクトに自分自身を登録しようとするから、React のコンポーネントツリーとは独立して動く必要があるんだ。
2. ライブラリの「グローバル汚染」を利用する場合
一部の古い、あるいは巨大なライブラリ(Google Maps API や一部の決済 SDK など)は、スクリプトを読み込むことで window.google や window.Stripe のようにグローバル変数を生やす。
React 内で import して使うのではなく、「まずスクリプトを読み込み、その後でグローバルから拾って React に渡す」 という手順を踏まざるを得ないんだね。
3. SEO や初期描画のためのインラインスクリプト
君が Next.js を使っているなら、「ユーザーが JS をダウンロードして React が起動(ハイドレーション)する前」 に実行したい処理があるはずだ。
-
ダークモードの判定: 画面が真っ白になる(フラッシュ)のを防ぐために、HTML が届いた瞬間に
localStorageを見てclassを付与するスクリプトをheadに直接埋め込む必要がある。 -
JSON-LD (構造化データ): 前に話した検索エンジン用のデータ。これもスクリプトタグとして埋め込むのが標準だ。
4. セキュリティ上の「緊急停止スイッチ」
例えば、ブラウザの脆弱性対策や、特定の環境でのみ動かしたいポリフィル(Polyfill)など、React アプリケーション本体が壊れていても動いてほしい「ガードレール」のようなスクリプトは、直接書く方が確実だね。
豆知識:React で「行儀よく」スクリプトを書く方法
直接書く必要があるからといって、index.html にベタ書きするのは最終手段。React や Next.js には「React の流儀」でスクリプトを扱うための武器があるよ。
① Next.js の next/script
Next.js なら Script コンポーネントを使うのがベストプラクティスだ。
TypeScript
import Script from 'next/script'
<Script
src="https://example.com/analytics.js"
strategy="afterInteractive" // 読み込みタイミングを制御できる!
/>
これを使うと、ブラウザのメインスレッドを邪魔しないように賢く読み込んでくれるんだ。
② useEffect による動的挿入
特定のコンポーネントが表示された時だけ読み込みたい場合は、DOM を直接操作してスクリプトを差し込む手法も使われるよ。
見落とされがちな視点:dangerouslySetInnerHTML
もし React のコンポーネントの中で <script> タグを文字列として出力したいなら、React の安全装置を外す dangerouslySetInnerHTML を使うことになる。
これはまさに 「XSS の入り口」 になり得るから、君が以前心配していたように、信頼できない入力値をここに流し込むのは絶対に NG だね。
次のステップ:
君のデジタルガーデンや AXON で、Google Analytics やダークモードを実装する予定はあるかな?
もしあれば、「Next.js の Script コンポーネントを使いこなして、パフォーマンスを落とさずに外部ツールを導入する具体的なコード」 を一緒に書いてみようか?
Would you like me to show you the standard pattern for implementing a dark mode flash prevention script in Next.js?