Callbacks
TaxKitProvider accepts four callback props for events that originate inside the iframe but need to be handled by your parent app — opening links in the host context, reacting to user actions, and forwarding partner-specific events back to your analytics layer.
onOpenLink
onOpenLink(href: string, options?: { target?: 'self' | 'blank' }) => voidInvoked when the iframe wants to open an external link (help articles, support pages, learn-more links).
href— the URL to open.options.target— reserved for future use. The iframe does not currently send atargetin production, so partners should treat every call as a new-tab open. The second parameter exists in the type signature for forward compatibility.
When omitted, the SDK falls back to a default of window.open(href, '_blank')?.focus() — note this does not include noopener / noreferrer. If you care about either (recommended for security), supply your own handler as shown below.
onOpenLink={(href) => {
// Recommended: add noopener,noreferrer for security
window.open(href, '_blank', 'noopener,noreferrer');
}}
Use this hook to route links through your existing in-app navigation logic, attach tracking parameters, or sandbox links through a click-interstitial.
onDisconnectUser
onDisconnectUser() => voidInvoked when the iframe disconnects the user from CoinTracker. Use it to clear partner-side caches of CoinTracker data, fire analytics, or trigger a UI reset.
onDisconnectUser={() => {
analytics.track('tax_kit_disconnected');
queryClient.invalidateQueries({ queryKey: ['cointracker'] });
}}
This is a one-way notification. To trigger a disconnect from your own UI, call disconnectUser() returned by useTaxKit().
onPartnerImportTransactionsSuccess
onPartnerImportTransactionsSuccess() => voidInvoked after a partner-side import succeeds following an OAuth round-trip. Use it to refresh your imports list, show a success toast, or fire a partner-specific analytics event.
onPartnerImportTransactionsSuccess={() => {
refreshImports();
toast.success('Imports refreshed from CoinTracker.');
}}
onReceivedAdditionalMetadata
onReceivedAdditionalMetadata(metadata: Record<string, unknown>) => voidInvoked when the iframe forwards partner-specific metadata back to the parent app. The shape is open-ended — coordinate with your CoinTracker integration owner on which keys you'll receive.
onReceivedAdditionalMetadata={(metadata) => {
analytics.track('tax_kit_metadata', metadata);
}}
onReceivedAdditionalMetadata is in active review at CoinTracker — it may be folded into a future generic onEvent analytics callback. Don't build business logic that depends on a specific key without confirming with your integration owner first.
Why these aren't grouped under options
Callbacks are inherently identity-sensitive (a fresh function on every render can trigger downstream effects). Keeping them at the top level makes the dependency boundary obvious to React's hooks rules and to your code-review tools. Wrap them in useCallback if your parent component re-renders frequently.