@thor-commerce/app-bridge-react
v0.9.0
Published
Communication bridge between embedded apps and the Thor Commerce dashboard
Downloads
2,148
Readme
@thor-commerce/app-bridge-react
Communication bridge between embedded apps and the Thor Commerce dashboard.
Repository link: thor-email-app
Installation
npm install @thor-commerce/app-bridge-reactCDN Runtime
The package now also builds a standalone browser runtime that can be hosted on a CDN.
Build it with:
pnpm buildThe CDN-friendly artifact is:
dist/thor-app-bridge.jsYou can load it before your app bundle:
<script
src="https://cdn.example.com/thor-app-bridge/thor-app-bridge.js"
data-client-id="your-client-id"
data-target-origin="https://dashboard.thorcommerce.com"
></script>For Shopify-like markup, the script also accepts data-api-key, but the value must still be the public Thor clientId, not the clientSecret.
That script:
- bootstraps a singleton runtime before React mounts
- patches same-origin
fetchto attach Thor session tokens - intercepts in-app navigation and reports sanitized paths back to the dashboard
- keeps embedded launch params on the iframe document URL
If you do not want auto-init, omit the data attributes and initialize it manually:
<script src="https://cdn.example.com/thor-app-bridge/thor-app-bridge.js"></script>
<script>
window.ThorAppBridge.init({
clientId: "your-client-id",
targetOrigin: "https://dashboard.thorcommerce.com",
});
</script>Core Usage
import { createAppBridge } from "@thor-commerce/app-bridge-react";
const bridge = createAppBridge({
source: "embedded-app",
target: "dashboard",
targetOrigin: "https://dashboard.thorcommerce.com"
});
bridge.send("app:ready", { version: "1.0.0" });
const session = await bridge.request<undefined, { shopId: string }>("session:get");
const sessionToken = await bridge.getSessionToken({ clientId: "your-client-id" });
bridge.on("navigation:update", (message) => {
console.log(message.payload);
});React Router
import { Outlet } from "react-router";
import { ReactRouterAppBridgeProvider } from "@thor-commerce/app-bridge-react/react-router";
export default function App() {
return (
<ReactRouterAppBridgeProvider clientId="your-client-id">
<Outlet />
</ReactRouterAppBridgeProvider>
);
}Next.js App Router
"use client";
import { NextAppBridgeProvider } from "@thor-commerce/app-bridge-react/next";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<NextAppBridgeProvider clientId="your-client-id">
{children}
</NextAppBridgeProvider>
);
}ReactRouterAppBridgeProvider and NextAppBridgeProvider automatically:
- create the bridge on the client
- attach to the singleton runtime when the browser script already initialized it
- send
app:ready - emit
navigation:updatewhen the route changes - listen for
navigation:goand push the app to the requested route
Custom React Apps
If you are not using React Router or Next.js, use AppBridgeProvider from the root package and pass currentPath and onNavigate yourself.
API
createAppBridge(options)creates a bridge instance and starts listening forpostMessageevents.AppBridgeProvidermanages the bridge lifecycle for React apps.useAppBridge()gives access to the underlying bridge instance for advanced cases.ReactRouterAppBridgeProviderandNextAppBridgeProviderare framework adapters with built-in navigation syncing.clientIdis the primary app identity input for the React providers. The provider infers the dashboard origin fromdocument.referrerin embedded contexts.bridge.send(type, payload)sends a fire-and-forget event.bridge.request(type, payload, options)sends a request and waits for a response.bridge.getSessionToken({clientId}, options)requests a short-lived embedded app session token from the dashboard.bridge.on(type, handler)subscribes to events. Use"*"to listen to every incoming message.bridge.onRequest(type, handler)registers a request handler that can reply with a value or promise.bridge.setTargetWindow(window)updates the destination window after construction.bridge.destroy()removes listeners and rejects pending requests.
Releases
- Publishing is handled by semantic-release from
main. - Use Conventional Commits so releases are created automatically:
fix:for patch,feat:for minor, andBREAKING CHANGE:for major. - npm publishing uses npm Trusted Publisher from GitHub Actions; no
NPM_TOKENis required.
