metabase-full-app-to-modular-embedding-upgrade について
Metabase の全アプリ埋め込みを利用する開発者向けのエージェントスキルです。Metabase のページを表示する iframe をモジュラー埋め込みの Web コンポーネントへ移行し、バージョン別ドキュメントに基づいて SSO、ページ設定、URL パラメーター、属性を対応付けます。
主な機能
- 01順序に沿った移行チェックリスト
- 02iframe、SSO、設定のスキャン
- 03ページ種別と Web コンポーネントの対応付け
- 04URL パラメーターと属性の変換
- 05変更の検証と根拠の報告
活用シーン
- 01ダッシュボード iframe のモジュラー埋め込み移行
- 02質問やコレクションページの Web コンポーネント化
- 03インスタンスのバージョンに応じた移行計画と検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ metabase/ agent-skills --skill metabase-full-app-to-modular-embedding-upgradeインストール後、Claude Code で/metabase-full-app-to-modular-embedding-upgradeを入力して読み込まれたか確認します。
詳細
実行契約
ワークフローの手順を順番に実行してください。どの手順も省略しないでください。まずチェックリストを作成し、その後、各手順を実行して、根拠を示しながら完了を明示してください。各手順の出力は次の手順に引き継がれます。手順を省略すると、移行が正しく行われません。
情報不足やツールのエラーにより手順を完了できない場合は、必ず次の対応を行ってください。
- 該当する手順を ❌ blocked として記録する。
- 何が不足しているのか、または何が失敗したのかを正確に説明する。
- そこで停止する(後続の手順には進まない)。
必須の出力構成
回答には、次のセクションをこの順序で含めてください。
- Step 0:Metabase バージョンの検出
- Step 0.1:移行計画チェックリスト
- Step 1:プロジェクトのスキャン
- Step 2:iframe の分析と Web コンポーネントのマッピング
- Step 3:移行計画
- Step 4:コード変更の適用
- Step 5:検証
- Step 6:最終概要
各手順のセクションは、次のステータス行で締めくくってください。
Status: ✅ completeまたはStatus: ❌ blocked
手順は順番に進めてください。前の手順が ✅ complete になるまで、次の手順を開始しないでください。
根拠に関する要件
- Step 0:検出した Metabase バージョン(情報源:Docker タグ、環境変数、またはユーザーの回答)。
- Step 1:一致したすべてのファイルパス、すべての iframe の場所、SSO エンドポイント、レイアウト/head ファイル、Metabase の設定変数。
- Step 2:各 iframe について、解析した URL、コンテンツの種類、ID、ハッシュパラメーター、属性を含む対応する Web コンポーネント。
- Step 3:変更前/変更後のコードを正確に示した、ファイルごとの完全な変更計画。
- Step 4:ファイルごとに、変更内容と適用した差分を正確に示す。
- Step 5:各検証チェックの合否と根拠。
アーキテクチャへの準拠
アプリで既に採用されているアーキテクチャ、テンプレートエンジン、レイアウト/パーシャルの仕組み、コードスタイル、ルーティングのパターンに従ってください。方式を切り替えないでください(例:テンプレートからインライン HTML への変更)。共有テンプレート変数用のミドルウェアがアプリにある場合は、ルートハンドラーごとに重複させるのではなく、そちらを優先してください。
パフォーマンス
- 各手順内で並列処理を最大限に活用してください。可能な場合は、Grep/Glob/Read の呼び出しを一度のメッセージで並列に実行してください。
- プロジェクトのスキャンにサブエージェントを使用しないでください。後の手順で相互参照できるよう、結果はメインコンテキスト内に保持してください。
- リポジトリのブランチ、コミット、PR、Issue を調べないでください。
対象範囲
このスキルでは、Full App/インタラクティブ埋め込み(iframe ベース)を、モジュラー埋め込み(embed.js を使った Web コンポーネントベース)に変換します。
利用側のアプリは、任意のバックエンド言語(Node.js、Python、Ruby、PHP、Java、Go、.NET など)と任意のテンプレートエンジンで構成されている場合があります。Step 1 で特定の言語が検出されない限り、言語に依存しない説明にしてください。
このスキルで対応する内容
- Metabase を参照する
<iframe>要素を、適切な Web コンポーネント(例:<metabase-question>、<metabase-dashboard>)に置き換える embed.jsの script タグを追加する(アプリのレイアウトレベルに正確に 1 回)window.metabaseConfigの設定コードを追加する(アプリのレイアウトレベルに正確に 1 回)- モジュラー埋め込みの JSON レスポンス形式に対応するよう、SSO/JWT エンドポイントを変更する
- iframe URL のカスタマイズパラメーターをテーマ設定とコンポーネント属性にマッピングする
このスキルの対象外
- Static(署名付き/ゲスト)埋め込みからの移行
使用可能なドキュメントソース
バージョンに対応する llms-embedding-full.txt を、次の URL から取得してください。
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 インスタンスのバージョンは必ず尋ねてください。コードによる検出だけに頼らないでください
- iframe の URL パターンが既知のリソースタイプ(ダッシュボード、質問、コレクション、ホーム)のいずれにも一致しない
- プロジェクト内で SSO/JWT エンドポイントを特定できない
- レイアウトファイルまたは head ファイルを特定できず、embed.js を挿入する場所が不明である
- レイアウトファイルが複数あり、どれを使用するか判断できない
- バックエンドの言語を特定できない
- 複数の iframe で異なる
locale値が指定されている(window.metabaseConfigに設定する locale をユーザーに尋ねてください)
ワークフロー開始前の手順
移行計画チェックリスト
進捗を追跡するためのチェックリストを作成してください。Claude Code では TaskCreate/TaskUpdate ツールを使用してください。
- Step 0: Metabase のバージョンを検出する
- Step 1: プロジェクトをスキャンし、対象バージョンのドキュメントを取得する
- Step 2: iframe を分析し、ウェブコンポーネントに対応付ける(ドキュメントを使用)
- Step 3: 移行の変更内容を計画する
- Step 4: コードを変更する
- Step 5: 変更を検証する
- Step 6: 最終的な概要をまとめる
ワークフロー
Step 0: Metabase インスタンスのバージョンを検出する
Metabase インスタンスのバージョンは必ず AskUserQuestion で尋ねてください。Docker タグや環境変数にバージョンが記載されている場合も、必ずユーザーに確認してください。v52 以前の場合は中止してください(モジュラー埋め込みは v53 で導入されました)。
次に、確認したバージョンの llms-embedding-full.txt を取得してください(URL 形式については「許可されているドキュメントソース」を参照)。
何よりも先に、Metabase のバージョンを特定してください。プロジェクト内で Docker イメージタグ(metabase/metabase:v、metabase/metabase-enterprise:v)、METABASE_VERSION、またはバージョンへの言及を Grep で検索してください。検出できない場合は AskUserQuestion を使用してください(選択肢:v52 or older、v53、v54–v58、v59+)。v52 以前の場合は中止してください(モジュラー埋め込みは v53 で導入されたため、利用できません)。バージョンを記録してください。このバージョンによって、後続の手順での jwtProviderUri の配置場所が決まります。
Step 1: プロジェクトをスキャンし、ドキュメントを取得する(サブエージェントなし)
プロジェクトのスキャンとドキュメントの取得は独立した作業なので、並行して実施してください。依存関係がない箇所では、1 つのメッセージ内でツール呼び出しを並行して行ってください。
1a: 対象バージョンのドキュメントを取得する
対象バージョンの llms-embedding-full.txt を取得してください(URL 形式については「許可されているドキュメントソース」を参照)。このドキュメントは、対象バージョンのウェブコンポーネント属性、window.metabaseConfig のオプション、SSO エンドポイントの動作に関する正式な情報源です。Step 2 での対応付けにはこのドキュメントを使用し、ハードコードされた表だけに頼らないでください。
以下のプロジェクトスキャン手順と並行して開始してください。
1b: バックエンドの言語とフレームワークを特定する
- 依存関係ファイル/ビルドファイル(
package.json、requirements.txt、Gemfile、pom.xml、go.mod、composer.jsonなど)を確認してください。 - テンプレートエンジンを特定し、言語とフレームワークを記録してください。
1c: Metabase の iframe をすべて見つける
Grep を使用して、次のパターンをすべて並行して検索してください。
- すべてのテンプレート/HTML/JSX/view ファイル内の
<iframe - すべてのサーバーサイドコードファイル(JS/TS/Python/Ruby/Go/Java/PHP)内の
iframe— 文字列連結やテンプレートリテラルで構築される iframe を検出します iframeまたはsrc属性の近くにあるauth/sso。注:SSO URL は別の変数や関数で構築され、iframe のsrcに渡される場合があります。iframe のsrcが変数の場合は、その定義をたどってauth/ssoが含まれているか確認してください。
一致があったファイルごとに、ファイル全体を読み込んでください。
1d: SSO/JWT 認証コードを見つける
Grep を使用して、次のパターンをすべて並行して検索してください。
/auth/sso/sso/metabaseまたは類似する SSO ルートパターンjwt.sign、jwt.encode、JWT、jsonwebtoken、PyJWT、joseJWT_SHARED_SECRETまたはMETABASE_JWT_SHARED_SECRETreturn_to(Metabase の SSO リダイレクトパラメーター)auth/ssoの近くにあるredirect(SSO リダイレクトのロジックを検出します)
一致があったファイルごとに、ファイル全体を読み込んでください。
1e:レイアウト/head ファイルを特定する
HTML の <head> セクションが定義されている単一のファイル(または共通のコードパス)を見つけます。ここに embed.js と window.metabaseConfig が挿入されます。
次を検索します。
- テンプレート/ビューのファイル内にある
<head>、<!DOCTYPE、または<html> - レイアウト/ラッパーのパターン:
include('head')、<%- include、{% extends、{% block、layout、base.html、_layout、application.html - アプリがサーバーコード内のインライン文字列(例:
res.send(...))で HTML を生成している場合は、<head>の内容が生成されている場所を特定します
1f:Metabase の設定を特定する
METABASE_ および MB_ をプレフィックスに持つ変数を Grep で検索します。Metabase 関連の変数名と、それが読み込まれる場所をすべて記録します。
出力:構造化されたプロジェクトインベントリ
調査結果をすべて次の形式にまとめます。
Backend: {language}, {framework}, {template engine}
Metabase config:
- Site URL variable: {name} (read at {file}:{line})
- Dashboard path variable: {name} (read at {file}:{line})
- JWT secret variable: {name} (read at {file}:{line})
- Other variables: ...
Layout/head file: {path}:{line range} (or "inline HTML in {file}:{line range}")
Iframes found: {count}
- {file}:{line} — {brief description}
- ...
SSO endpoint: {file}:{line} — {route} ({method})
ステップ 2:iframe を分析し、Web コンポーネントに対応付ける(ステップ 1 ✅ の完了後のみ)
Web コンポーネントの属性、window.metabaseConfig のオプション、および SSO エンドポイントの動作については、ステップ 1a で取得したドキュメントを正確な参照元として使用します。以下の固定テーブルは代替情報です。対象バージョンのドキュメントに追加の属性や異なる動作が記載されている場合は、ドキュメントを優先してください。
ステップ 1 で見つかった iframe ごとに、次を行います。
2a:iframe の URL を解析する
iframe の src 属性(テンプレート式、変数、またはリテラルの場合があります)から、次の情報を抽出します。
- Metabase のベース URL:環境変数、定数、またはハードコードされた値の場合があります
- リソースのパス:ベース URL の後ろにあるパス。例:
/dashboard/1、/question/entity/abc123、/collection/5 - リソースの種類:
dashboard、question、collection、またはhome(パスが/の場合) - エンティティ ID または数値 ID:パス内のリソース識別子。
- ID は次のいずれかです。
- 数値 ID。例:123
- 数値 ID +スラッグ。例:123-slug。スラッグは完全に削除する必要があります。スラッグを含めるとリソースを読み込めません。
- エンティティ ID —
/{resource_type}/entity/{entity_id}のパターンに一致する URL では、エンティティ ID が使用されます
- ID は次のいずれかです。
- UI のカスタマイズに使用される URL ハッシュ/クエリパラメーター(例:
#logo=false&top_nav=false) - SSO によるラッピング:iframe がまず SSO エンドポイントを経由するかどうか(例:
/sso/metabase?return_to=...)
2b:コンテンツの種類を Web コンポーネントに対応付ける
| フルアプリの iframe パスパターン | モジュラー Web コンポーネント | 必須属性 |
|---|---|---|
/dashboard/{id} または /dashboard/entity/{entity_id} | <metabase-dashboard> | dashboard-id="{id or entity_id}" |
/question/{id} または /question/entity/{entity_id} | <metabase-question> | question-id="{id or entity_id}" |
/model/{id} または /model/entity/{entity_id} | <metabase-question> | question-id="{id or entity_id}" |
/collection/{id} または /collection/entity/{entity_id} | <metabase-browser> | initial-collection="{id or entity_id}" |
/(Metabase のホーム/ルート) | <metabase-browser> | initial-collection="root" |
iframe のパスが変数から動的に組み立てられている場合は、Web コンポーネントの属性にも同じ変数/式を使用します。
iframe のパスが既知のパターンに一致しない場合 → AskUserQuestion。
2c: URL カスタマイズパラメーターのマッピング
削除するパラメーター(該当しません — モジュール型 Web コンポーネントには Metabase アプリケーションのクロームが含まれないためです):
| フルアプリのパラメーター | 削除する理由 |
|---|---|
top_nav | Web コンポーネントには Metabase のトップナビゲーションバーがありません |
side_nav | Web コンポーネントには Metabase のサイドバーがありません |
logo | Web コンポーネントには Metabase またはホワイトラベルのロゴがありません |
search | Web コンポーネントには Metabase の検索バーがありません |
new_button | + New ボタンはありません(該当する場合は、<metabase-browser> で with-new-question / with-new-dashboard を使用してください) |
breadcrumbs | Web コンポーネントには Metabase のパンくずリストがありません |
Web コンポーネントの属性にマッピングするパラメーター:
| フルアプリのパラメーター | モジュール型の同等機能 |
|---|---|
header=false | コンポーネントの with-title="false" |
action_buttons=false | コンポーネントの drills="false" |
window.metabaseConfig にマッピングするパラメーター:
| フルアプリのパラメーター | metabaseConfig のプロパティ |
|---|---|
locale={code} | locale: "{code}" |
ロケールの移行ルール:
- すべての iframe でロケール値が 1 つだけ見つかった場合 →
window.metabaseConfigにlocale: "{code}"を自動的に追加します - iframe 間で異なるロケール値が複数見つかった場合 → ユーザーが
window.metabaseConfigに設定するロケールを 1 つ選べるよう、AskUserQuestion を表示します(モジュール型の埋め込みでサポートされるグローバルロケールは 1 つのみです)
2d: 移行マッピング表の出力
各 iframe について、以下を出力します。
iframe #{n}: {file}:{line}
Old: {full iframe HTML or code}
Content type: {dashboard|question|collection|home}
ID: {static value or variable expression}
Dropped params: {list}
Mapped attributes: {list}
New: {exact replacement web component HTML}
ステップ 3:移行内容を計画する(ステップ 2 の完了後のみ ✅)
以下のすべての領域を対象に、ファイルごとの変更計画を作成します。すべての変更について、対象ファイル、変更前のコード、変更後のコードを指定してください。
3a: embed.js スクリプトの挿入 — アプリごとに 1 回のみ
- 対象:ステップ 1e で特定したレイアウト/head ファイル
- 場所:
<head>内(または他の<script>タグにできるだけ近い場所) - 追加するコード:
<script defer src="{METABASE_SITE_URL}/app/embed.js"></script> {METABASE_SITE_URL}は、プロジェクトで既に使用されているテンプレート式の構文を使って動的に出力してください。- Metabase URL 変数が特定のルートでしか利用できない場合は、ミドルウェアまたはテンプレートコンテキストを介してレイアウトに渡してください。
- ユーザーがどのページを訪問しても、レンダリングされた HTML にこのコードが 1 回だけ含まれることを確認してください。2 回読み込まれると SDK が再初期化され、認証状態が壊れます。
3b: metabaseConfig — アプリごとに 1 回のみ
モジュール型の埋め込みでは、window.metabaseConfig から設定を読み取ります。defineMetabaseConfig() 関数はありません。設定オブジェクトを直接割り当ててください。
- 対象:3a と同じレイアウト/head ファイル
- 場所:embed.js のスクリプトタグより前(設定は embed.js の読み込み前に行う必要があります。そうしないと SDK が読み取る設定を取得できません)
- 追加するコード(最小限 — 認証フィールドは、取得したドキュメントにこのバージョンでサポートされると記載されている場合にのみ追加してください):
<script> window.metabaseConfig = { instanceUrl: "{METABASE_SITE_URL}", // Add auth fields here only if supported by the confirmed version's docs }; </script> - ロケール:ステップ 2c でいずれかの iframe に
localeパラメーターが見つかった場合、設定オブジェクトにlocale: "{code}"を追加してください。複数の iframe で異なるロケール値が見つかった場合は、AskUserQuestion の条件に従い、使用するロケールをユーザーに確認済みです。 instanceUrl(およびサポートされている場合はjwtProviderUri)は、プロジェクトで既に使用されているテンプレート式の構文を使って動的に出力してください。- 認証設定フィールド:ステップ 0 で取得したドキュメントを参照し、確認済みのバージョンが
window.metabaseConfigでサポートするフィールドを確認してください。たとえば、jwtProviderUriはサポートされる場合とされない場合があります。ドキュメントに記載されている場合は、完全な絶対 URL(例:http://localhost:9090/sso/metabase)として指定してください。相対パスは機能しません。ドキュメントに記載されていない場合は、代わりに JWT Identity Provider URI を Metabase の管理設定で構成する必要があります(ステップ 3f を参照)。 window.metabaseConfigは 1 回だけ設定してください。レイアウトではなく iframe ごとのコードに記述すると、各コンポーネントが SDK を再初期化します。
3c:SSO エンドポイントの変更
既存の SSO エンドポイントは、現在、ブラウザーを Metabase の /auth/sso?jwt={token}&return_to={path} にリダイレクトします。
モジュラー埋め込みでは、embed.js SDK は JWT Identity Provider URI に fetch リクエストを送信し、JSON レスポンスを期待します。エンドポイントを JSON のみを返すように変更してください。以前のリダイレクトベースの認証フローへのフォールバックは残さないでください。
これは段階的な移行ではなく、全面的な移行です。以前の iframe ベースの埋め込みは完全に置き換えられるため、リダイレクト動作は不要になります。
確認済みのバージョンにおける SSO エンドポイントの想定レスポンス形式については、Step 0 で取得した認証ドキュメントを参照してください。
制約:
- JWT 署名ロジックは変更しないでください。変更するのはレスポンスの返し方だけです。
- 古いリダイレクト動作は完全に削除してください。エンドポイントは JSON のみを返す必要があります。
- JSON レスポンス本文は
{ "jwt": "<token>" }のみとしてください。SDK はこの正確な形式を解析するため、他のフィールドを含めないでください。 - リダイレクト URL を構築するコード(例:
new URL("/auth/sso", ...)、searchParams.set("return_to", ...))は不要になったため削除してください。
3d:iframe の置き換え計画
Step 2d の移行マッピング表にある iframe ごとに、以下を指定してください。
- ファイルパス、置き換え対象となる正確な既存コード、正確な新しいコード
- 新しい Web コンポーネントでは、元の iframe URL に含まれていた動的 ID 式を維持してください。
- iframe に明示的な
width/height属性またはインラインstyleがある場合は、それらを Web コンポーネント要素に直接適用してください(例:<metabase-dashboard dashboard-id="1" style="width:800px;height:600px">)。<div>で囲まないでください。 - iframe のスタイルが CSS クラスで指定されていた場合は、そのクラスを Web コンポーネントに直接適用してください。
- iframe がスタイル付きのコンテナ要素内にあった場合は、そのコンテナを維持してください。
- iframe の src にのみ使用されていたサーバーサイドの SSO URL 構築(例:
/sso/metabase?return_to=...の構築)は削除してください。ただし、SSO エンドポイント自体は削除しないでください。モジュラー埋め込みの認証に引き続き必要です。 - iframe の src が、インライン HTML を返すサーバーサイドのルートハンドラー(例:Express の
res.send('<iframe ...'))を介して構築されていた場合は、そのハンドラーのレスポンス文字列内の iframe HTML を置き換えてください。
3e:不要コードの削除
iframe の置き換えと SSO エンドポイントの変更後、以下を特定して削除してください。
- iframe の
srcURL を構築していた変数(例:iframeUrl、mbUrl)で、他の場所でも使われていないもの - iframe URL に追加されていた URL パラメーター/修飾文字列(例:
mods = "logo=false")で、他の場所から参照されていないもの(SSO エンドポイントを確認してください。リダイレクトロジックを削除した場合、これらの文字列も不要になっている可能性があります) - SSO エンドポイントから削除されたリダイレクト関連コード(例:
/auth/ssoの URL 構築、return_toパラメーターの処理)。これは Step 3c の一環としてすでに対応済みです。 - Metabase iframe URL を構築するヘルパー関数で、他の場所から呼び出されていないもの
- 削除しないもの:SSO エンドポイント自体、JWT 署名関数、環境変数の読み取り、アプリケーションの他の部分で使用されているコード
3f:Metabase 管理者設定に関する注意事項(ユーザーが手動で行う手順)
計画の一部として以下を列挙してください。最終的な要約に含めます。
- モジュラー埋め込みを有効化:Admin > Embedding > 「Enable modular embedding」を切り替えます。
- CORS オリジンを設定:Admin > Embedding > Modular embedding > ホストアプリのドメイン(例:
http://localhost:9090)を追加します。 - JWT Identity Provider URI を設定:Admin > Authentication > JWT > SSO エンドポイントの完全な URL(例:
http://localhost:9090/sso/metabase)を設定します。これが確認済みのバージョンで必須か任意かを判断するため、取得したドキュメントを確認してください(window.metabaseConfigが JWT プロバイダーフィールドをサポートしているかどうかによります)。 - JWT 共有シークレット:変更は不要です。Full App 埋め込み設定で使用している既存の共有シークレットを再利用します。
ステップ 4:コード変更を適用する(ステップ 3 ✅ の完了後のみ)
ステップ 3 のすべての変更を、以下の順序で適用します(問題が発生する時間を最小限にするため、バックエンドの変更を先に行います)。
- 最初に:SSO エンドポイントを変更して JSON を返すようにします(ステップ 3c)。これはバックエンドのみの変更です
- 次に:レイアウト/head ファイルに
window.metabaseConfigの代入と embed.js の script タグを追加します(ステップ 3b + 3a、設定を embed.js より前に配置) - 3 番目に:各 iframe を Web コンポーネントに置き換えます(ステップ 3d)。1 ファイルずつ行います
- 4 番目に:不要なコードを削除します(ステップ 3e)
制約:
- すべての変更に対し、Edit ツールを使って
old_string/new_stringを正確に指定してください - 新しいパッケージ依存関係を追加しないでください。モジュール型埋め込みに必要なのは、Metabase インスタンスが配信する embed.js スクリプトのみです
- 環境変数名を変更しないでください
- 1 つのファイルに複数の編集が必要な場合は、オフセットの問題を避けるため、上から順に適用してください
ステップ 5:変更を検証する(ステップ 4 ✅ の完了後のみ)
以下のチェックをすべて実行します。チェック 5a~5c は互いに独立した grep 検索のため、並行して実行できます。チェック 5d と 5e では、指定されたファイルを読み込む必要があります。各チェックについて、明確な合格/不合格の結果を示してください。
5a:Metabase の iframe が残っていないこと
Grep を使って、node_modules、.git、ロックファイルを除くプロジェクト内のすべてのファイルから <iframe と iframe を検索します。
Metabase を参照する Full App/Interactive Embedding の iframe が残っていないことを確認してください。
Metabase 以外の iframe は変更しないでください。また、ゲスト埋め込み(以前の「静的埋め込み」)やパブリック埋め込みの iframe も変更しないでください。これらは異なる URL パターン(例:/embed/ や /public/)を使用し、この移行の対象外です。
合格基準:Full App/Interactive Embedding の iframe が 0 件であること(ゲスト/パブリック埋め込みの iframe は除外)。
5b:embed.js が正確に 1 回だけ出現すること
Grep を使って、node_modules と .git を除くプロジェクト内のすべてのファイルから /app/embed.js を検索します。このパターンは Metabase の埋め込みスクリプト URL に固有のもので、汎用的な embed.js というファイル名を使う他のツールによる誤検出を避けられます。
合格基準:レイアウト/head ファイル内に正確に 1 件だけ出現すること。
5c:window.metabaseConfig が正確に 1 回だけ設定されていること
Grep を使って、node_modules と .git を除くプロジェクト内のすべてのファイルから window.metabaseConfig を検索します。
合格基準:レイアウト/head ファイル内の代入箇所に、正確に 1 件だけ出現すること。
5d:SSO エンドポイントが JSON のみを返すこと
SSO エンドポイントのファイルを読み込み、以下を確認します。
- エンドポイントが
{ jwt: token }を含む JSON レスポンスを返す - 古いリダイレクトロジック(
res.redirect、new URL("/auth/sso", ...)、return_to)がすべて削除されている - JSON が唯一のレスポンス形式であるため、
response=jsonの条件チェックが存在しない
合格基準:エンドポイントが JSON のみを返し、リダイレクトへのフォールバックが残っていないこと。
5e:変更したファイルを抜き取り確認する
変更した各ファイルを読み込み、以下を確認します。
- Web コンポーネントに必須属性(
dashboard-id、question-id、またはinitial-collection)がある - テンプレート構文が有効である(タグが閉じられており、式が正しい)
- ステップ 3e で特定した不要なコードの変数が削除されている
合格基準:すべてのチェックに合格すること。
チェックに失敗した場合:
- 問題をすぐに修正します
- 該当するチェックを再実行します
- 3 回試しても修正できない場合は、ステップ 5 を ❌ ブロックとし、失敗したチェックとその理由を報告します
ステップ 6:出力の概要
最終出力を次のセクションに整理します。
- 適用した変更:変更したすべてのファイルを列挙し、それぞれの変更内容を一行で説明します
- Web コンポーネントの対応関係:各旧 iframe → 新しい Web コンポーネントを示す表
- 削除したパラメーター:削除した Full App iframe パラメーターの一覧と、モジュール型の埋め込みには適用されない理由の簡単な説明
- テーマの設定:
window.metabaseConfigにマッピングしたテーマ/外観設定 - 必要な手動作業(ステップ 3f の Metabase 管理者設定):
- モジュール型の埋め込みを有効にする
- CORS オリジンを設定する
- JWT Identity Provider URI を設定する
- 特定されたその他の管理者向け手順
- ユーザーが把握しておくべき動作の違い:
- ユーザーは単一の埋め込み内でダッシュボード/質問/コレクション間を移動できなくなります(各 Web コンポーネントは独立しています)
- Metabase アプリケーションシェル(ナビゲーション、サイドバー、検索)は表示されなくなります
- マッピングできなかった iframe パラメーター
再試行ポリシー
ドキュメントの取得:
llms-embedding-full.txtの取得時に 404 が返された場合は、Metabase のバージョン番号を確認して再試行します。それでも失敗する場合は、ステップ 1 を ❌ ブロックとして記録します。
検証:
- ステップ 5 の検証チェックで、修正を 3 回試みた後も失敗するものがある場合は、ステップ 5 を ❌ ブロックとして記録し、失敗したチェックとその理由を報告します。
- AskUserQuestion に回答がない場合は、そのステップでブロックされた状態を維持します。推測したり、仮定に基づいて先に進んだりしないでください。