mcpField
M
metabase-static-embedding-to-guest-embedding-upgrade

metabase-static-embedding-to-guest-embedding-upgrade

github.com/metabase開発54360 回インストール1 日前に更新
リポジトリ

metabase-static-embedding-to-guest-embedding-upgrade について

Metabase の静的署名埋め込みを保守する開発者向けのエージェントスキルです。既存の JWT 署名処理を維持しながら、iframe を `embed.js` 経由のゲスト埋め込み Web コンポーネントへ段階的に移行します。

主な機能

  1. 01順序に沿った移行チェックリスト
  2. 02静的埋め込みと設定のスキャン
  3. 03iframe から Web コンポーネントへの対応付け
  4. 04JWT 署名処理の維持
  5. 05変更の検証と根拠の報告

活用シーン

  1. 01署名付きダッシュボード iframe のゲスト埋め込み移行
  2. 02署名付き質問 iframe の Web コンポーネント置換
  3. 03バージョンに応じた移行の計画と検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/metabase/agent-skills --skill metabase-static-embedding-to-guest-embedding-upgrade

インストール後、Claude Code で/metabase-static-embedding-to-guest-embedding-upgradeを入力して読み込まれたか確認します。

詳細

実行手順

ワークフローの手順を順番どおりに実行してください。手順を飛ばしてはいけません。まずチェックリストを作成し、その後、各手順を実行して、証拠を示しながら完了を明示してください。各手順の出力は次の手順に引き継がれるため、手順を飛ばすと誤った移行につながります。

情報不足やツールの失敗により手順を完了できない場合は、必ず次の対応を行ってください。

  1. 手順を ❌ blocked と記録する。
  2. 何が不足しているか、何が失敗したかを正確に説明する。
  3. 停止する(後続の手順に進まない)。
必須の出力構成

回答には、次のセクションをこの順序で含めてください。

  1. ステップ 0 の結果:Metabase バージョンの検出
  2. ステップ 0.1:移行計画のチェックリスト
  3. ステップ 1 の結果:プロジェクトのスキャンとドキュメントの取得
  4. ステップ 2 の結果:静的埋め込みの分析と Web コンポーネントへのマッピング
  5. ステップ 3:移行計画
  6. ステップ 4:コード変更の適用
  7. ステップ 5:検証
  8. ステップ 6:最終サマリー

各ステップのセクションは、次のいずれかのステータス行で終えてください。

  • Status: ✅ complete または Status: ❌ blocked

ステップは順番に実行してください。前のステップが ✅ complete になるまで、次のステップを開始してはいけません。

証拠の要件
  • ステップ 0:検出した Metabase のバージョン(情報源:Docker タグ、環境変数、またはユーザーの回答)。
  • ステップ 1:一致したファイルパスをすべて、静的埋め込みの箇所をすべて、JWT 署名コード、レイアウト/head ファイル、Metabase 設定変数、取得したドキュメントの一覧。
  • ステップ 2:埋め込みごとに、解析した iframe URL、コンテンツタイプ、トークン変数、ハッシュパラメーター、属性を含むマッピング先の Web コンポーネント。
  • ステップ 3:ファイルごとの変更計画をすべて記載し、変更前後のコードを正確に示す。
  • ステップ 4:ファイルごとに、変更内容と適用した差分を正確に示す。
  • ステップ 5:各検証チェックの合否結果と証拠。
アーキテクチャへの準拠

アプリの既存のアーキテクチャ、テンプレートエンジン、レイアウト/パーシャルの仕組み、コードスタイル、ルートのパターンに従ってください。方式を切り替えてはいけません(例:テンプレートからインライン HTML への変更)。アプリにテンプレート共通変数用のミドルウェアがある場合は、ルートハンドラーごとに重複させるのではなく、それを優先してください。

Web コンポーネントは、置き換える静的 iframe と同じ配信方法でレンダリングしてください。iframe がサーバーサイドテンプレート(EJS、Jinja、ERB、Blade など)でレンダリングされている場合、Web コンポーネントも同じテンプレートでレンダリングしてください。iframe がルートハンドラーからインライン HTML(例:res.send('<iframe ...'))として返されている場合、Web コンポーネントも同じ方法で返してください。iframe が静的 HTML ファイルに記述されている場合、Web コンポーネントも同じファイルに記述してください。レンダリングを別のレイヤーに移してはいけません。移行は、レンダリングパイプライン内の同じ箇所での置き換えとして行ってください。

トークンの受け渡しには、元の静的埋め込みと同じ方法を使用してください。 JWT が HTML にサーバーサイドで埋め込まれていた場合(例:res.send(\`))、移行後の Web コンポーネントにも同じ方法でトークンを渡してください。つまり、サーバーサイドで token 属性に埋め込みます(例:)。JWT がクライアントサイドで fetch()を使って取得されていた場合は、トークンにも引き続きfetch()` を使用してください。受け渡し方法を変更せず、渡すものだけを変更してください(iframe URL 全体ではなく、生のトークンを渡します)。

認証情報の安全性

この移行では、METABASE_SECRET_KEY と署名付き JWT を扱うコードに触れます。次のルールに従ってください。

  • 秘密情報の値をそのまま出力してはいけません。コード内にハードコードされた秘密鍵やトークン文字列が見つかった場合は、変数名だけで参照してください(例:「config.js:12 にある秘密情報」)。値そのものを出力してはいけません。
  • コード差分とサマリーでは、解決後の値ではなく、変数参照(METABASE_SECRET_KEY、token)を使用してください。
  • ハードコードされた秘密情報が見つかった場合は、ユーザーに注意喚起し、移行の一環として環境変数に移すことを推奨してください。

パフォーマンス

  • 各ステップ内で並列処理を最大化してください。可能な限り、1 回のメッセージで Grep/Glob/Read を並列に呼び出してください。
  • プロジェクトのスキャンにサブエージェントを使用しないでください。後続のステップで相互参照できるよう、結果はメインコンテキスト内に保持する必要があります。
  • リポジトリのブランチ、コミット、PR、Issue を解析しないでください。

対象範囲

このスキルは、静的な(署名付き)iframe の埋め込みを、ゲスト埋め込み(embed.js を介した Web コンポーネントベースの埋め込み)に変換します。どちらの方式も、METABASE_SECRET_KEY を使用した署名付き JWT という同じ認証モデルを使用するため、バックエンドの署名ロジックはそのまま維持されます。移行によって変わるのは、署名済みコンテンツの配信方法です。JWT を URL に含む iframe から、token 属性を持つ Web コンポーネントに変わります。

利用側のアプリは、どのバックエンド言語(Node.js、Python、Ruby、PHP、Java、Go、.NET など)でも、どのテンプレートエンジンでも作成できます。Step 1 で特定の言語が検出されない限り、言語に依存しない手順にしてください。

このスキルで扱う内容
  • 署名付きの <iframe> 要素(/embed/dashboard/{JWT}、/embed/question/{JWT})を Web コンポーネント(<metabase-dashboard token="...">、<metabase-question token="...">)に置き換える
  • embed.js のスクリプトタグを追加する(アプリのレイアウトレベルに 1 回だけ)
  • isGuest: true を設定した window.metabaseConfig を追加する(アプリのレイアウトレベルに 1 回だけ)
  • iframe のハッシュパラメーター(#titled=true、#bordered=true)を Web コンポーネントの属性に対応付ける
  • 既存の JWT 署名ロジックを維持する。バックエンドは引き続き METABASE_SECRET_KEY を使用して、同じ {resource, params} ペイロードでトークンに署名します。
  • 署名済みトークンをフロントエンドに渡す方法を変更する(iframe の URL パスから、テンプレート変数を token 属性に渡す方法に変更)
  • 該当する場合、JWT 内のロックされた params を initial-parameters 属性に対応付ける
  • 存在する場合は iframeResizer.js の参照を削除する
このスキルで扱わない内容
  • SSO ベースのモジュール型埋め込み(ユーザーアカウントを使用)への移行。このスキルの対象はゲスト埋め込みのみです。
ゲスト埋め込みと静的な iframe 埋め込みの違い

認証モデルは同じです。どちらも METABASE_SECRET_KEY を使って {resource, params, exp} を含む JWT に署名します。変わるのは埋め込みのレンダリング方法です。

項目静的埋め込み(iframe)ゲスト埋め込み(Web コンポーネント)
要素<iframe src="/embed/dashboard/{JWT}#params"><metabase-dashboard token="{JWT}">
トークンの受け渡しiframe の URL パスに埋め込むtoken 属性として渡す
設定なし(iframe は単独で動作)window.metabaseConfig = { isGuest: true, instanceUrl: "..." }
スクリプトiframeResizer.js(任意)embed.js(必須)
外観ハッシュパラメーター(#titled=true)コンポーネント属性(with-title="true")
ロックされたパラメーターJWT の params フィールド同じ JWT の params フィールド(変更なし)
シークレットキーMETABASE_SECRET_KEY同じ METABASE_SECRET_KEY

ゲスト埋め込みでは、静的な埋め込みでは利用できない追加属性(ダウンロード、ドリルスルー、非表示パラメーターなど)がサポートされています。対象バージョンで利用できる属性の一覧については、取得したドキュメントを参照してください。

許可されているドキュメントソース

次の URL を使用して、バージョン固有の llms-embedding-full.txt を取得してください。

https://www.metabase.com/docs/v0.{VERSION}/llms-embedding-full.txt

URL のバージョンには v0.58 の形式を使用します(正規化:先頭の v または 0. を削除し、パッチ番号を除外します。例:0.58.1 → 58 → URL では v0.58 を使用)。この単一ファイルには、そのバージョンの埋め込みに関するすべてのドキュメントが含まれており、LLM での利用に最適化されています。

その他の制約:

  • GitHub の PR/Issue や npm のページは使用しないでください。
  • GitHub の変更履歴へのリンクをたどったり、URL を推測したりしないでください。

AskUserQuestion を使う条件

次の場合は AskUserQuestion を使用し、回答があるまで処理を中断してください。

  • プロジェクトのコードまたは環境変数から Metabase インスタンスの URL を特定できない場合
  • バックエンド言語を特定できない場合
  • プロジェクトのコードから Metabase インスタンスのバージョンを特定できない場合
  • embed.js を挿入する場所となるレイアウト/head ファイルを特定できない場合
  • 複数のレイアウトファイルがあり、どれを使用すべきか判断できない場合

ワークフロー前の手順

移行計画チェックリスト

進捗を追跡するチェックリストを作成します。Claude Code では、TaskCreate/TaskUpdate ツールを使用します。

  • Step 0:Metabase のバージョンを検出
  • Step 1:プロジェクトをスキャンし、対象バージョンのドキュメントを取得
  • Step 2:静的埋め込みを分析し、ウェブコンポーネントに対応付け(ドキュメントを使用)
  • Step 3:移行の変更を計画
  • Step 4:コードを変更
  • Step 5:変更を検証
  • Step 6:最終的な概要

ワークフロー

Step 0:Metabase のバージョンを検出

何よりも先に、Metabase のバージョンを特定します。Docker イメージタグ(metabase/metabase:v、metabase/metabase-enterprise:v)、METABASE_VERSION、またはバージョンの記述をプロジェクト内で Grep 検索します。検出できない場合は、AskUserQuestion を使用します(選択肢:v53 or older、v54–v58、v59+)。v53 未満の場合は中止します(モジュール式埋め込みは利用できません)。バージョンを記録します。

Step 1:プロジェクトをスキャンし、ドキュメントを取得

プロジェクトのスキャンとドキュメントの取得は独立しているため、並行して実行します。依存関係がない箇所では、1 つのメッセージ内で並列ツール呼び出しを使用します。

1a:対象バージョンのドキュメントを取得

対象バージョンの llms-embedding-full.txt を取得します(URL 形式については「許可されているドキュメントのソース」を参照)。これらのドキュメントは、対象バージョンのウェブコンポーネントの属性、window.metabaseConfig のオプション、ゲスト埋め込み設定についての信頼できる情報源です。ハードコードされた表だけに頼らず、Step 2 での対応付けに使用します。

以下のプロジェクトスキャン手順と並行して開始します。

1b:バックエンドの言語とフレームワークを特定
  • 依存関係/ビルドファイル(package.json、requirements.txt、Gemfile、pom.xml、go.mod、composer.json など)を確認します。
  • テンプレートエンジンを特定し、言語とフレームワークを記録します。
1c:既存のモジュール式埋め込み設定を確認

アプリにモジュール式埋め込みがすでに設定されているかを検出するため、以下のパターンを(並行して)Grep 検索します。

  • /app/embed.js — 既存の embed.js スクリプトタグ
  • window.metabaseConfig — 既存の設定代入

それぞれがすでに存在するか、またどこにあるかを記録します。両方がすでに存在する場合(例:アプリがモジュール式埋め込みと静的埋め込みを併用している場合)、Step 3a と 3b では追加を行いません。

1d:静的埋め込みコードをすべて見つける

Grep を使用して、以下のすべてのパターンを検索します(並行して実行)。

  • すべてのファイル内の /embed/dashboard/ — 静的埋め込みダッシュボード URL
  • すべてのファイル内の /embed/question/ — 静的埋め込み質問 URL
  • すべてのテンプレート/HTML/JSX/ビューのファイル内の <iframe — 埋め込み要素
  • METABASE_SECRET_KEY または METABASE_EMBEDDING_SECRET_KEY — 署名シークレット
  • dashboard または question の近くにある resource: — JWT ペイロードの構造
  • iframeResizer — オプションの自動リサイズスクリプト

一致があったファイルは、それぞれ全体を読み取ります。

1e:JWT 署名コードを見つける

Grep を使用して、以下のすべてのパターンを検索します(並行して実行)。

  • jwt.sign、jwt.encode、JWT、jsonwebtoken、PyJWT、または jose
  • METABASE_SECRET_KEY または MB_EMBEDDING_SECRET_KEY
  • resource: と params: の組み合わせ(静的埋め込み JWT ペイロードの形式)

一致したファイルは、それぞれ全体を読み取ります。

1f:レイアウト/head ファイルを見つける

HTML の <head> セクションが定義されている単一のファイル(または共通のコードパス)を見つけます。ここに embed.js と window.metabaseConfig を挿入します(Step 1c ですでに存在する場合を除きます)。

以下を検索します。

  • テンプレート/ビューファイル内の <head>、<!DOCTYPE、または <html
  • レイアウト/ラッパーのパターン:include('head')、<%- include、{% extends、{% block、layout、base.html、_layout、application.html
  • サーバーコード内のインライン文字列(例:res.send(...))で HTML を構築している場合は、<head> の内容が生成されている箇所を特定します
1g:Metabase の設定を見つける

METABASE_ および MB_ を接頭辞とする変数を Grep 検索します。Metabase 関連の変数名と、それぞれが読み取られている場所をすべて記録します。

出力:構造化されたプロジェクトインベントリ

以下にすべての調査結果をまとめます。

Backend: {language}, {framework}, {template engine}
Metabase config:
  - Site URL variable: {name} (read at {file}:{line})
  - Secret key variable: {name} (read at {file}:{line})
  - Other variables: ...
Layout/head file: {path}:{line range}
Static embeds found: {count}
  - {file}:{line} — {brief description} (dashboard/question, ID: {id})
  - ...
JWT signing: {file}:{line} — {library used}
JWT payload: resource type={dashboard|question}, params={list or "none"}
iframeResizer: {present|not present}
Existing modular embedding: {embed.js: yes/no, metabaseConfig: yes/no}
ステップ 2:静的埋め込みを分析し、Web コンポーネントに対応付ける(ステップ 1 ✅ の後のみ)

ステップ 1a で取得したドキュメントを、Web コンポーネントの属性、window.metabaseConfig オプション、ゲスト埋め込みの動作に関する正式な参照資料として使用します。以下のハードコードされた表は代替情報です。対象バージョンについて、ドキュメントに追加の属性や異なる動作が記載されている場合は、ドキュメントを優先してください。

ステップ 1 で見つかった静的埋め込みごとに、次の作業を行います。

2a:署名付き iframe URL を解析する

iframe の src 属性から次の情報を抽出します。

  • Metabase のベース URL:環境変数、定数、またはハードコードされた値の場合があります
  • リソースの種類:dashboard または question(/embed/{type}/ パスから判別)
  • リソース ID:JWT の resource フィールドにある数値 ID(例:resource: { dashboard: 10 })
  • ロックされたパラメーター:JWT ペイロード内の params(例:params: { category: ["Gadget"] })
  • ハッシュパラメーター:# 以降の外観設定(例:#titled=true&bordered=false)
  • iframeResizer の使用状況:この iframe に対して iFrameResize() が呼び出されているかどうか
2b:コンテンツの種類を Web コンポーネントに対応付ける
静的埋め込み URL のパターンモジュラー Web コンポーネント必須属性
/embed/dashboard/{JWT}<metabase-dashboard>token="{JWT}"
/embed/question/{JWT}<metabase-question>token="{JWT}"

token 属性には、以前 iframe URL に埋め込まれていたものと同じ署名付き JWT を設定します。バックエンドの署名コードはそのままで、変更するのは配信方法だけです。

テンプレート内でトークンが動的に生成されている場合(例:src="<%= metabaseUrl %>/embed/dashboard/<%= token %>")、トークン変数を取り出して token 属性に渡します(例:token="<%= token %>")。

2c:ハッシュパラメーターを対応付ける

Web コンポーネントの属性に対応するパラメーター:

静的埋め込みのハッシュパラメーターゲスト埋め込みでの対応
titled=true/falseコンポーネントの with-title="true/false"
bordered=true/false直接対応するものはありません。削除します(Web コンポーネントには枠線の装飾がありません)
refresh=N直接対応するものはありません。削除します(Metabase インスタンスの設定で処理されます)
theme=night代わりに window.metabaseConfig.theme を使用します(対象バージョンでサポートされている場合)
2d:ロックされたパラメーターと編集可能なパラメーターを対応付ける

ロックされたパラメーター(JWT の params フィールド内):変更は不要です。JWT 内に保持され、これまでと同じように機能します。署名付きトークンにはすでに含まれています。

編集可能なパラメーター:静的埋め込みでユーザーがフィルターを操作できた場合、initial-parameters 属性で初期値を設定できます。

<metabase-dashboard
  token="{JWT}"
  initial-parameters='{"category":["Doohickey","Gizmo"]}'
></metabase-dashboard>

initial-parameters は、ユーザーが変更できるフィルターのデフォルト値を設定します。これは静的な iframe 埋め込みでは利用できなかった新しい機能です。

2e:移行対応表を出力する

静的埋め込みごとに、次の形式で出力します。

embed #{n}: {file}:{line}
  Old: {iframe HTML or signing + iframe code}
  Content type: {dashboard|question}
  Token variable: {template expression for the signed JWT}
  Locked params: {in JWT — no change needed}
  Hash params: {list or "none"}
  Dropped params: {list}
  Mapped attributes: {list}
  New: {exact replacement web component HTML}
ステップ 3:移行の変更内容を計画する(ステップ 2 ✅ の後のみ)

以下のすべての領域を網羅する、ファイルごとの完全な変更計画を作成します。各変更について、対象ファイル、変更前のコード、変更後のコードを明記してください。

3a:metabaseConfig — アプリごとに一度だけ

ステップ 1c で既存の window.metabaseConfig の割り当てが見つかった場合、このステップは省略してください。 既存の設定に isGuest: true がない場合は、新たに作成せず、既存の設定にそのフィールドを追加します。

  • 対象:ステップ 1f で特定したレイアウト/head ファイル
  • 配置場所:<head> 内、embed.js の script タグより前(設定は embed.js の読み込み前に行う必要があります)
  • 追加するコード:
    <script>
      window.metabaseConfig = {
        isGuest: true,
        instanceUrl: "{METABASE_SITE_URL}",
      };
    </script>
    
  • isGuest: true は必須です。これにより、embed.js は SSO モードではなくゲスト(署名付きトークン)モードを使用します。
  • instanceUrl は、プロジェクトのテンプレート式構文を使用して動的に出力してください。
  • ロケール:静的埋め込みのハッシュに locale パラメーターが見つかった場合は、設定オブジェクトに locale: "{code}" を追加します。
  • 対象バージョンでサポートされる追加の window.metabaseConfig オプション(例:theme、font)については、取得したドキュメント(ステップ 1a)を確認してください。
  • window.metabaseConfig は一度だけ設定してください。
3b:embed.js スクリプトの挿入 — アプリごとに正確に1回

Step 1c で既存の embed.js スクリプトタグが見つかった場合は、この手順をスキップしてください。

  • 対象:3a と同じレイアウト/head ファイル
  • 場所:<head> 内の window.metabaseConfig スクリプトの後(embed.js は読み込み時に設定を読み取ります)
  • 追加するコード:
    <script defer src="{METABASE_SITE_URL}/app/embed.js"></script>
    
  • {METABASE_SITE_URL} は、プロジェクトで既に使用しているテンプレート式構文を使って動的に出力してください。
  • ユーザーがどのページを訪問しても、レンダリングされた HTML にこれが正確に1回だけ含まれることを確認してください。
3c:バックエンドのトークン受け渡しをリファクタリング

バックエンドには、トークンを生成する JWT 署名コードが既にあります。現在は完全な iframe URL(/embed/dashboard/{token}#params)を構築しています。署名ロジックはそのままにしますが、トークンをフロントエンドに渡す方法を変更します。

  • 変更前:バックエンドが完全な iframe URL 文字列を構築してテンプレートに渡し、テンプレートが <iframe src="{url}"> をレンダリングします
  • 変更後:バックエンドが署名済みトークンのみをテンプレートに渡し、テンプレートが <metabase-dashboard token="{token}"> をレンダリングします

Step 1d で見つかった署名箇所ごとに、次の手順を実施します。

  1. JWT 署名呼び出し(jwt.sign(payload, METABASE_SECRET_KEY))は変更せずに残します
  2. {baseUrl}/embed/dashboard/ を先頭に付加し、ハッシュパラメーターを末尾に追加する URL 構築コードを削除します
  3. 完全な URL ではなく、生のトークン文字列をテンプレートコンテキストに渡します

署名処理が共有関数ではなくテンプレートハンドラー内に直接記述されている場合は、そのハンドラーだけを変更します。

3d:iframe の置き換え計画

Step 2e の Migration Mapping Table にある iframe ごとに、次の内容を指定します。

  • ファイルパス、置き換える正確な既存コード、正確な新コード
  • 新しい Web コンポーネントでは、{token_variable} に署名済み JWT のテンプレート式を指定して token="{token_variable}" を使用します
  • Step 2c に従って、ハッシュパラメーターをコンポーネント属性に割り当てます
  • スタイルを維持する:iframe のサイズ指定を Web コンポーネント要素に直接引き継ぎます。ラッパーの <div> は不要です。
    • iframe に width/height HTML 属性またはインライン style が指定されていた場合は、それらを Web コンポーネントに直接適用します(例:<metabase-dashboard token="..." style="width:800px;height:600px">)
    • iframe に CSS クラスでスタイルが適用されていた場合は、それらのクラスを Web コンポーネントに直接適用します
    • iframe がサイズを既に制御しているコンテナー内にある場合、追加のスタイル指定は不要です。Web コンポーネントはそのコンテナーいっぱいに広がります
    • iframe で自動高さ調整に iframeResizer を使用していた場合は削除します。Web コンポーネントは自身のサイズを処理します
  • この iframe に関連する iframeResizer の呼び出しをすべて削除します
3e:不要なコードの削除

iframe の置き換え後、次のコードを特定して削除します。

  • /embed/dashboard/{token}#params または /embed/question/{token}#params 文字列を構築する URL 構築コード
  • iframeResizer.js スクリプトタグと、すべての iFrameResize() 呼び出し
  • ハッシュパラメーター文字列の構築(例:const mods = "titled=true&bordered=false")
  • 静的な埋め込み iframe URL の構築にのみ使用されていたヘルパー関数

次のものは削除しないでください。

  • JWT 署名コード(jwt.sign(payload, METABASE_SECRET_KEY))— 引き続き使用します
  • METABASE_SECRET_KEY 環境変数 — 引き続き使用します
  • JWT ライブラリのインポート — 引き続き使用します
  • アプリケーションの他の部分で使用されているコード
3f:Metabase 管理者設定に関する注意事項(ユーザーが手動で行う手順)

これらを計画の一部として列挙してください。最終的な概要に含めます。

  1. モジュラー埋め込みを有効にする:Admin > Embedding > 「Enable modular embedding」を切り替えます
  2. ゲスト埋め込みを有効にする:Admin > Embedding > 「Guest embedding」(古い UI では「Static embedding」)が有効になっていることを確認します。既存の静的埋め込みシークレットキーを再利用します。
  3. CORS オリジンを設定する:Admin > Embedding > Security > ホストアプリのドメイン(例:http://localhost:9090)を追加します。これは新しい設定です。静的 iframe 埋め込みでは CORS 設定は不要でした。
ステップ 4:コード変更を適用する(ステップ 3 ✅ の完了後のみ)

ステップ 3 のすべての変更を、次の順序で適用します。

  1. 最初に:レイアウト/head ファイルに window.metabaseConfig の代入と embed.js の script タグを追加します(ステップ 3a + 3b。config を embed.js より前に配置)
  2. 次に:バックエンドでのトークンの受け渡しをリファクタリングします。署名処理は維持し、URL の構築は削除します(ステップ 3c)
  3. 3 番目に:各 iframe を Web コンポーネントに置き換えます(ステップ 3d)。ファイルごとに進めます
  4. 最後に:不要なコードを削除します。iframeResizer、URL ビルダー(ステップ 3e)

制約:

  • すべての変更には、Edit ツールを使い、正確な old_string/new_string を指定します
  • 新しいパッケージ依存関係を追加しないでください。モジュラー埋め込みに必要なのは、Metabase インスタンスが配信する embed.js スクリプトのみです
  • METABASE_SECRET_KEY を変更または削除しないでください。引き続き署名に使用します
  • 1 つのファイルに複数の編集が必要な場合は、オフセットの問題を避けるため、上から順に適用します
ステップ 5:変更を検証する(ステップ 4 ✅ の完了後のみ)

次のチェックをすべて実施します。各チェックについて、合格または不合格を明示してください。

5a:静的な埋め込み iframe が残っていない

Grep を使って、node_modules、.git、ロックファイルを除くプロジェクト内のすべてのファイルから /embed/dashboard/ と /embed/question/ を検索します。

合格基準:静的な埋め込み URL の構築が 1 件も見つからないこと(コメントにはパターンが残っている場合があります。その場合は、実行コードではないことを確認してください)。

5b:embed.js が 1 か所だけに記述されている

Grep を使って、node_modules と .git を除くプロジェクト内のすべてのファイルから /app/embed.js を検索します。

合格基準:レイアウト/head ファイルに 1 件だけ記述されていること。

5c:window.metabaseConfig が 1 か所だけで設定されている

Grep を使って、node_modules と .git を除くプロジェクト内のすべてのファイルから window.metabaseConfig を検索します。

合格基準:isGuest: true を含む記述が 1 件だけあること。

5d:JWT 署名コードが維持されている

JWT 署名ファイルを読み込み、次を確認します。

  • jwt.sign(または同等の処理)の呼び出しが残っている
  • METABASE_SECRET_KEY が引き続き環境変数から読み込まれている
  • JWT ペイロードに resource フィールドと params フィールドが引き続き含まれている

合格基準:署名ロジックが維持されていること。

5e:iframeResizer の参照が残っていない

Grep を使って、プロジェクト内のすべてのファイルから iframeResizer と iFrameResize を検索します。

合格基準:参照が 1 件も残っていないこと(または、無関係なコードにのみ含まれていること)。

5f:変更したファイルを抜き取り確認する

変更した各ファイルを読み込み、次を確認します。

  • Web コンポーネントに、正しいテンプレート式を持つ token 属性がある
  • テンプレート構文が有効である(タグが閉じられており、式が正しい)
  • ステップ 3e で特定した不要なコードが削除されている

合格基準:すべてのチェックに合格すること。

いずれかのチェックに不合格となった場合:

  • 直ちに問題を修正します
  • 該当するチェックを再実行します
  • 3 回試しても修正できない場合は、ステップ 5 を ❌ ブロックとしてマークし、不合格となったチェックとその理由を報告します
ステップ 6:出力の概要

最終出力を次のセクションに整理します。

  1. 適用した変更:変更したファイルをすべて列挙し、それぞれの変更内容を1行で説明します
  2. Web コンポーネントの対応表:各旧署名付き iframe と新しい Web コンポーネントの対応を示す表:
    | File | Old | New |
    |---|---|---|
    | views/analytics.ejs | <iframe src="/embed/dashboard/{token}#titled=true"> | <metabase-dashboard token="{token}" with-title="true"> |
    
  3. 変更されなかった点:JWT 署名ロジック、METABASE_SECRET_KEY、JWT の params フィールド内の固定パラメーター
  4. 削除したパラメーター:削除した静的埋め込みハッシュパラメーターの一覧と、簡単な説明
  5. 新たに利用できる機能:静的 iframe 埋め込みでは利用できなかった、今回利用可能になった機能:
    • 編集可能なフィルターのデフォルト値を指定する initial-parameters 属性
    • ダウンロードを有効にする with-downloads 属性(Pro/Enterprise)
    • モバイル対応の向上(Web コンポーネントはコンテナーに合わせて調整されます)
  6. 必要な手動作業(ステップ 3f の Metabase 管理者設定):
    • モジュール型埋め込みを有効にする
    • ゲスト埋め込みが有効になっていることを確認する(既存のシークレットキーを再利用します)
    • CORS オリジンを設定する(新しい要件)
  7. ユーザーが把握しておくべき動作の違い:
    • Web コンポーネントはコンテナー全体に広がります。iframe に固定サイズを指定していた場合は、コンテナーに適切なサイズが設定されていることを確認してください
    • bordered の外観オプションは利用できなくなりました。Web コンポーネントは枠なしで表示されます
    • 自動更新(refresh=N)は埋め込みごとに設定できなくなりました。代わりに Metabase インスタンスの設定で構成してください

再試行ポリシー

ドキュメントの取得:

  • llms-embedding-full.txt の取得時に 404 が返された場合は、Metabase のバージョン番号を確認して再試行してください。それでも取得できない場合は、ステップ 1 を ❌ ブロック中として記録します。

検証:

  • ステップ 5 の検証チェックで、修正を3回試みても失敗するものがあれば、ステップ 5 を ❌ ブロック中として記録し、失敗したチェック項目とその理由を報告してください。
  • AskUserQuestion に回答がない場合は、そのステップでブロックされた状態を維持してください。推測したり、仮定に基づいて進めたりしないでください。

コメント