--- name: metabase-modular-embedding-to-modular-embedding-sdk-upgrade description: Migrates a React project from Metabase Modular embedding (embed.js web components) to the Modular embedding SDK (@metabase/embedding-sdk-react). Use when the user wants to switch from embed.js web components to React SDK components (MetabaseProvider). This is not a version upgrade — it changes the embedding technology. model: opus allowed-tools: Read, Write, Edit, Glob, Grep, Bash, WebFetch, Task, TaskCreate, TaskUpdate, TaskList, TaskGet, AskUserQuestion --- ## Execution contract Follow the workflow steps in order — do not skip any step. Create the checklist first, then execute each step and explicitly mark it done with evidence. Each step's output feeds into the next, so skipping steps produces wrong migrations. If you cannot complete a step due to missing info or tool failure, you must: 1. record the step as ❌ blocked, 2. explain exactly what is missing / what failed, 3. stop (do not proceed to later steps). ### Required output structure Your response should contain these sections in this order: 1. **Step 0: Prerequisites Check** 2. **Step 0.1: Migration Plan Checklist** 3. **Step 1: Project Scan** 4. **Step 2: Target SDK API** 5. **Step 3: Migration Mapping** 6. **Step 4: Applied Code Changes** 7. **Step 5: Typecheck Validation** 8. **Step 6: Final Summary** Each step section should end with a status line: - `Status: ✅ complete` or `Status: ❌ blocked` ### Evidence requirements - Step 0: React detected (dependency + version), Metabase instance version, target SDK version, package manager. - Step 1: every file with Modular embedding usage (web components, metabaseConfig, embed.js script tag), with matching grep lines. - Step 2: confirm d.ts loaded in context. List exported components, their props, and the MetabaseProvider config type. - Step 3: the structured migration mapping — every web component → React component with prop conversions, auth config mapping, and embed.js removal plan. - Step 4: per file — what was changed and exact diffs applied. - Step 5: the exact typecheck command run and error summary if any remain. ## Credential safety This migration touches code that may contain API keys, JWTs, or auth configuration values (e.g., `window.metabaseConfig`). Rules: - **Never output literal secret values** — if you encounter a hardcoded API key, token, or secret in the code, reference it by variable name or file location (e.g., "the key in `config.js:12`"), never echo the value itself - In code diffs and summaries, use variable references — not the resolved values - If you find hardcoded secrets, flag them to the user and recommend moving them to environment variables as part of the migration ## Performance The workflow is designed as a pipeline: ``` Round 1 (grep+glob+pkg) ──► Round 2 (prepare.sh) ──► Round 3 (read-sources.sh) ──► Step 3 (mapping, inline) │ Step 4 per-file: ├── Convert FileA ├── Convert FileB └── Convert FileC │ Step 5 (typecheck) ──► Step 6 ``` In Claude Code, use parallel tool calls or `run_in_background: true` for sub-agents. Do not parse repo branches, commits, PRs, or issues — they're noisy and irrelevant. ### Tool-call round budget for Steps 1+2 Steps 1+2 must complete in **3 tool-call rounds**. **Round 1** — discovery (all concurrent, single message): - Grep for `metabase-dashboard`, `metabase-question`, `metabase-browser` in `*.{jsx,tsx,js,ts}` files - Grep for `window.metabaseConfig` - Grep for `/app/embed.js` (to find the script tag) - Read `package.json` (to confirm React dependency and detect package manager) - Glob for lock files (`yarn.lock`, `pnpm-lock.yaml`, `package-lock.json`) - `npm view @metabase/embedding-sdk-react version` (if target not specified by user) All tool calls in one message. **Round 2** — `prepare.sh` + fetch docs (concurrent): ```bash bash /scripts/prepare.sh {TARGET_VERSION} ``` Downloads the target SDK npm package and extracts it. Outputs `SDK_TMPDIR` and d.ts availability. In the same message, fetch `llms-embedding-full.txt` for the target version (see "Allowed documentation sources" for URL format). **Round 3** — `read-sources.sh` (single Bash call): ```bash bash /scripts/read-sources.sh {SDK_TMPDIR} ``` Dumps the target SDK's d.ts type definitions to stdout. After Round 3, output Step 1 Results + Step 2 Results + Step 3 Migration Mapping with zero additional tool calls. Produce Step 3 inline right after the data is loaded. ## Scope This skill converts Modular embedding (web-components-based) used inside a React app to the Modular embedding SDK (`@metabase/embedding-sdk-react`). The project must already be a React application with Modular embedding web components in JSX/TSX files. If the project is not React-based, this skill does not apply. If the project uses iframes instead of web components, use the `metabase-full-app-to-modular-embedding-upgrade` skill instead. ### What this skill handles - Replacing ``, ``, `` web components in JSX/TSX with their SDK React equivalents - Installing the `@metabase/embedding-sdk-react` npm package - Adding `` at the appropriate level in the React component tree - Converting `window.metabaseConfig` to `MetabaseProvider` config props - Removing the `embed.js` ` ``` ### Step 2: Fetch target SDK API Run `prepare.sh` in Round 2 (see round budget). Then `read-sources.sh` in Round 3 to load the d.ts into context. If d.ts is available, extract from it: - All exported React components (e.g., `MetabaseProvider`, dashboard/question/collection components) - Their prop types (resolved to concrete types, not just alias names) - The `MetabaseProvider` config type (what fields it accepts) - The auth config type The embedding docs (`llms-embedding-full.txt`) fetched in Round 2 provide supplementary reference for component usage, configuration options, and migration guidance. Use them alongside the d.ts for a complete picture. If d.ts is not available (SDK versions before 0.52.0 do not ship a single `index.d.ts`), use the embedding docs as the primary API reference instead. If neither d.ts nor docs are available, mark Step 2 ❌ blocked. ### Step 3: Build migration mapping (after Steps 1–2 are ✅ complete) **Scope: only map components and config actually found in Step 1's scan.** Produce a mapping that covers: #### Component mapping For each web component found in Step 1, identify the SDK React equivalent from the d.ts. Map attributes to props: ``` ## Migration Mapping ### → {SDK dashboard component from d.ts} - `dashboard-id` → `dashboardId` (camelCase) - `with-title` → `withTitle` (boolean prop) - `drills` → check d.ts for equivalent prop name - Other attributes → map to corresponding React props from d.ts ### → {SDK question component from d.ts} - `question-id` → `questionId` (camelCase) - Other attributes → map from d.ts ### → {SDK collection component from d.ts} - `initial-collection` → check d.ts for prop name - Other attributes → map from d.ts ``` For each mapping, resolve the target prop type to its concrete type. If an attribute has no SDK equivalent, note it as "dropped (not supported in SDK)" or "requires alternative approach". #### Auth config mapping Map `window.metabaseConfig` fields to `MetabaseProvider` config: ``` ### Auth & Config - window.metabaseConfig.instanceUrl → config.metabaseInstanceUrl (check d.ts for exact field name) - window.metabaseConfig.jwtProviderUri → authConfig.jwtProviderUri or authConfig.authProviderUri or config.authProviderUri (check d.ts — the field was renamed from `jwtProviderUri` to `authProviderUri` in some versions) - window.metabaseConfig.locale → locale prop or config field (check d.ts) ``` The d.ts is the authoritative source for field names — do not guess. If a `window.metabaseConfig` field has no equivalent in the SDK config type, note it. #### MetabaseProvider placement Determine where to add ``: - Find the highest common ancestor component that contains all Modular embedding web components - Typically this is the app root (`App.tsx`, `App.jsx`, or equivalent) - The provider must wrap all SDK components but should not unnecessarily wrap the entire app if components are isolated to a subtree #### Removal plan - embed.js `