🙅‍♂️

WordPressの記事内に書いたJSを動かしたい←やめて

に公開

結論

「CMS上の記事にJavaScriptを書いて動かしたい」という要望には、エンジニアとしては“No”と答えるべき。

理由:

  • 表示制御の責任が不明瞭になる
  • セキュリティリスクが高すぎる(XSSなど)
  • SPA構成では意図通りに動かない
  • 保守性・再利用性・デバッグ性すべてが下がる

ユーザーの要望(よくあるパターン)

WordPressの記事中にJavaScript書いたら、ユーザーの操作に応じてアラートを出したいんだけど?

→ 構成によってはリロード時には動くが、SPA遷移時には動かない
→ セキュリティ・運用面でもやってはいけない


構成

  • CMS(例:WordPress)でコンテンツ管理
  • フロントエンドは静的サイトジェネレーター(例:Nuxt、Next)で構築
  • 静的HTMLとしてビルド、CDN等でホスティング
  • ページ遷移はクライアントサイドで処理される(SPA構成)

問題

  • CMSの記事本文にJSを埋め込んでも動作しない
  • ページリロード直後、URLを直接開いたときはJSが動く
  • クライアントサイド遷移(SPA)時はJSが動かない

原因

  • 静的HTMLに含まれる<script>は初回ロード時のみ実行される
  • SPAのページ遷移はHTML差し替えのみで、JSは再評価されない
  • DOM上にあっても、ブラウザは再実行しない

一時的な解決策(非推奨)

やろうと思えば、以下のようにフロント側でJSを無理やり実行させることはできる。

plugin例(Nuxt想定)

// plugins/embed-script.client.ts
export default defineNuxtPlugin(() => {
  onNuxtReady(() => {
    const scripts = document.querySelectorAll('[data-embedded-script]');
    scripts.forEach((el) => {
      try {
        const code = el.textContent || '';
        const fn = new Function(code);
        fn();
      } catch (e) {
        console.error('Script execution error:', e);
      }
    });
  });
});

CMS側のマークアップ例

<div>
  <input id="sample-input" value="こんにちは" />
</div>

<div data-embedded-script>
  const val = document.getElementById('sample-input')?.value;
  if (val) alert(val);
</div>

evalFunctionを使う時点でXSSリスクが高く、保守不能。おすすめしない


なぜやってはいけないのか

設計の問題

  • 表示ロジックがCMSに混入し、責任が不明瞭になる
  • 非エンジニアがJSを書き始めると品質が保証できない
  • ロジックの再利用性や型安全性が消滅する

セキュリティの問題

  • JSを自由に埋め込める構成はXSSの温床
  • 悪意あるJSでユーザーのクッキーや入力情報を盗まれる
  • CSPとの整合性が取れず、セキュリティポリシー導入が難しくなる

運用の問題

  • 表示仕様の変更がCMS依存になり、移行や設計変更が困難に
  • 自動テストでの動作保証ができない
  • 障害調査時の責任分界が曖昧になる

正しい設計方針

  • 表示に関わるJSはフロントエンド側が持つ
  • CMSは構造化されたデータのみを提供する
  • フロントがそのデータを解釈して描画・動作を制御する

例:CMSからの構造化データ

{
  "type": "formEmbed",
  "formId": "1234"
}

→ フロント側で "type": "formEmbed" を判定して該当するUIコンポーネントを描画


まとめ

  • CMSにJSを書かせる構成は動作もセキュリティも保守性も破綻する
  • 一時的に動かす手段はあっても、根本的に「やってはいけない設計」
  • JSは常にフロント側が責任を持ち、CMSはデータ提供に徹するべき

Discussion