Routing and events

Link to screens inside your app, open native Tringify pages, and respond to merchant actions.

Admin App Bridge supports two kinds of navigation. Use bridge.navigate() to open a native page in the current store. Use bridge.routing.setPath() to keep the browser URL in step with a screen inside your embedded app. Host events carry the merchant's actions back to your app.

Open a Tringify admin page#

bridge.navigate(path) opens a native page for the store currently being managed. Pass a clean route such as /products or /orders/ORDER_ID. To open one tab of a page, add ?tab=NAME, and &section=NAME for a section inside it, for example /settings?tab=email; these are the only query parameters accepted, and they must name a tab that exists. Absolute URLs, protocol-relative URLs, other query parameters, fragments, whitespace, and . or .. path segments are rejected. The merchant's permissions still apply on the destination page.

javascript
await bridge.navigate("/products");

Make an in-app screen linkable#

Call bridge.routing.setPath(path) after your own router completes a merchant-initiated route change. The path belongs to your app and must begin with a single /. It may include your query string and fragment. Tringify stores it in the parent admin URL without reloading the iframe. Reporting the same path again does not add another browser-history entry.

javascript
myRouter.afterEach(async (to) => {
  await bridge.routing.setPath(to.fullPath);
});

A copied link, reload, or Back and Forward action arrives as routing:navigate with { path }. Route your app to that path without reporting it back to the host. Calling setPath() in response would describe the same movement twice and can create a routing loop in your app.

javascript
const stopRouting = bridge.on("routing:navigate", ({ path }) => {
  myRouter.replace(path);
});

// Call stopRouting() when this screen no longer owns the listener.

Subscribe to host events#

bridge.on(name, handler) returns a function that removes the listener. The SDK accepts ready and the declared host events below. A misspelled or unsupported event name throws UNSUPPORTED_EVENT immediately.

Event

Payload

When it is emitted

theme:change

{ theme: "light" | "dark" }

The merchant changes the admin colour theme.

routing:navigate

{ path }

A deep link or browser-history action requests an in-app route.

titlebar:action

{ id }

The merchant selects a title-bar action.

nav:navigate

{ id }

The merchant selects an item in the app navigation.

banner:action

{ id }

The merchant selects the banner action.

banner:dismiss

null

The merchant dismisses a dismissible banner.

savebar:save

null

The merchant selects Save in the host save bar.

savebar:discard

null

The merchant selects Discard in the host save bar.

fullscreen:change

{ fullscreen }

The host changes fullscreen state, including when the merchant uses the host exit control.

ready is the initial bridge lifecycle signal and carries the launch context. Prefer await bridge.ready() during startup. Register a ready listener before the handshake only when an event-style bootstrap is more convenient.

javascript
const stopTheme = bridge.on("theme:change", ({ theme }) => {
  document.documentElement.dataset.theme = theme;
});

const stopFullscreen = bridge.on("fullscreen:change", ({ fullscreen }) => {
  updateFullscreenControls(fullscreen);
});

Close the embedded app#

bridge.close() closes the embedded surface and returns the merchant to the installed-apps list. Use it after a flow that intentionally finishes the app session; do not use browser history or an absolute admin URL to imitate this behavior.

javascript
await bridge.close();

Open one product or one store policy#

navigate() can open a single item instead of a list. /products/{productId} opens that product's editor. /pages/policies/{type} opens one store policy's editor, where type is privacy, terms, refund, shipping or cookie. The same paths work in Store Admin and in the mobile app; the merchant's permissions still apply.

If your app needs certain policies, for example a sales channel that requires a published refund and shipping policy, read GET /policies (scope read_pages). Each policy has a status of draft or published, its content and, once published, its storefront_url. List what is missing and give each item a button that calls bridge.navigate('/pages/policies/' + type). Check bridge.supports('navigate') first, and read the list again when the merchant comes back to your app.