Skip to main content

Migrating from 2.1

In @cointracker/tax-kit@2.2.0 the TaxKitProvider prop surface was reorganized into grouped sub-objects (theme, options, metadata, copy). The flat shape from 2.1 still works — each legacy prop is preserved as a @deprecated alias and logs a console.warn once per browser session — but it will be removed in a future major version.

When both the new shape and a legacy prop are passed, the new shape wins.

Prop relocation table

2.1 prop2.2 location
apiBaseUrloptions.apiBaseUrl
hostPageUrloptions.hostPageUrl
modeoptions.mode
flowoptions.flow
overlayModeoptions.overlayMode
defaultOpenoptions.defaultOpen
hideNavigationBaroptions.hideNavigationBar
hideBackButtonoptions.hideBackButton
helpLinkUrloptions.helpLinkUrl
themeContracttheme.light / theme.dark
themeModetheme.mode
userPromoCodemetadata.promoCode

Side-by-side example

Before:

<TaxKitProvider
fetchAccessToken={fetchAccessToken}
apiBaseUrl="https://embedded.cointracker.com"
themeMode="dark"
themeContract={{ light: lightTokens, dark: darkTokens }}
mode="production"
flow="one-way"
defaultOpen={false}
userPromoCode="PARTNER_2026"
helpLinkUrl="https://help.your-partner.com/tax"
>
<YourApp />
</TaxKitProvider>

After:

<TaxKitProvider
fetchAccessToken={fetchAccessToken}
theme={{ mode: 'dark', light: lightTokens, dark: darkTokens }}
options={{
apiBaseUrl: 'https://embedded.cointracker.com',
mode: 'production',
flow: 'one-way',
defaultOpen: false,
helpLinkUrl: 'https://help.your-partner.com/tax',
}}
metadata={{ promoCode: 'PARTNER_2026' }}
>
<YourApp />
</TaxKitProvider>

Inline object literals for theme are functionally fine — the provider destructures primitives — but if your parent component re-renders frequently, memoize the nested theme objects to avoid redundant CONFIG messages to the iframe. See provider/theme for the detailed pattern.

Reserved metadata keys

One key inside metadata has special handling:

  • promoCode (string) — applied as the user's CoinTracker promo code. Replaces the legacy userPromoCode top-level prop.

Pass null to metadata.promoCode to explicitly clear a value — this prevents fall-through to the legacy userPromoCode prop if both are present.

Everything else inside metadata passes through opaquely to the iframe. See the Metadata reference for the full pattern.

Props removed in 2.2.0

Four props were removed entirely (not deprecated). Partners passing them will get a TypeScript compile error on upgrade.

themeClassName

Removed. The iframe wrapper now derives its class directly from theme.mode — partners no longer need to think about Tailwind custom variants or pass any className.

Why it's safe: the iframe SDK's bundled CSS had zero Tailwind utilities using the ct-embedded-dark:* or pro:* custom variants that themeClassName values were declared against. The only functionally important piece — providing a .dark ancestor so base-ui's dark:* utilities can fire — is now handled automatically by applying theme.mode.

Removed. The iframe now resolves the partner logo directly from the JWT-derived partner identity (embeddedHealth.partnerId) via the iframe's internal icon registry. Partners no longer need to pass a separate logo override.

If your integration needs a logo that doesn't match your JWT-derived partner key, contact your CoinTracker integration owner — the new icon goes into the iframe's registry, not the partner-side API.

startRoute and ?startRoute= URL forwarding

Removed. Investigation showed the feature was effectively a no-op in production: canonical state-driven routing in the iframe overrode startRoute in nearly every case. Partners passing it were paying for behavior that wasn't actually navigating users anywhere.

If you need deep-linking into the kit, contact your CoinTracker integration owner — we will design it as a proper feature rather than reviving the half-wired version.

partnerCostBasisMethodsByYear

Removed. This prop and its iframe-side machinery were removed entirely. The dedicated Record<number, CostBasisMethod> pipe had been built speculatively, but no UI component ever consumed it.

Partners who pass cost-basis information should use the metadata.costBasisMethodInfo key instead — a different key that the iframe actually reads (consumed by CostBasisMethodMismatchWarningOverlay). Coordinate with your CoinTracker contact on the exact shape.

Console warnings

Each deprecated prop fires one console.warn per browser session — deduped at module scope so a re-mount doesn't spam. The warning names both the deprecated prop and its new location:

[TaxKit] `apiBaseUrl` is deprecated and will be removed in a future major version. Use `options.apiBaseUrl` instead.

You can ignore these in production builds, but they're a good signal for tracking down lingering legacy usage in your codebase.

Find every legacy usage in your code

Grep your codebase for the deprecated prop names:

# Run from your repo root
grep -rnE \
"apiBaseUrl|hostPageUrl|themeMode|helpLinkUrl|themeContract|hideNavigationBar|hideBackButton|defaultOpen|userPromoCode|overlayMode|partnerCostBasisMethodsByYear|themeClassName|overridePartnerLogo|startRoute" \
--include='*.tsx' --include='*.ts' --include='*.jsx' --include='*.js' \
src/

Some of these names (mode, flow) are too generic to grep blindly — search for them in the context of <TaxKitProvider instead:

# Lines mentioning TaxKitProvider, with 20 lines after each
grep -rnA20 'TaxKitProvider' --include='*.tsx' --include='*.ts' src/ | less

Step through the matches and rewrite to the grouped shape using the relocation table above. The four removed props will be TypeScript compile errors after the upgrade — they'll surface themselves.