Skip to content

@pyrx/synapse-browser/ui

In-app messages, rendered for you

The core SDK delivers in-app messages to a callback and lets you draw every pixel. If you just want a sensible default, the optional UI Kit ships pre-built, themeable modal and banner renderers — a separate subpath export, so it adds zero bytes to your bundle when you don't import it.

Live demo

This page runs the published package

The demo below imports renderModal and renderBanner straight from @pyrx/synapse-browser/ui — the exact package on npm. What you see is what you ship.

Try it live

These buttons call the published package directly. No account, no API key, no network — just the real renderers with mock messages.

Rendered by @pyrx/synapse-browser/ui v0.4.0 — the same code you get from npm.

Integration

Five lines to a working in-app message

Install the package, wire attachUIKit to a placement, and every fresh message on that placement renders itself — dismiss and CTA telemetry wired automatically.

1. Install

npm
npm install @pyrx/synapse-browser

2. Attach the kit

app.ts
import { synapse } from "@pyrx/synapse-browser";
import { attachUIKit } from "@pyrx/synapse-browser/ui";

synapse("init", { apiKey: "psk_prod_xxx" });
synapse("identify", "user-123");
attachUIKit(synapse, { placement: "home_modal", layout: "modal" });

Full control

Or render it yourself

Call the renderers directly inside your own inApp.show callback when you need to control placement, timing, or stacking. Each render returns a handle with the mounted element and a close() method.

  • Modal: role="dialog", focus trap, Escape + backdrop dismiss, focus restored on close.
  • Banner: role="status", non-blocking — no focus trap, no Escape.
  • All text rendered via textContent; every URL funnelled through a strict http(s)/relative-only sanitizer.
  • Self-contained: no web fonts, no CDN. Namespaced under .pyrx-ui so it won't collide with your styles.
render.ts
import { renderModal, renderBanner } from "@pyrx/synapse-browser/ui";

// Inside your own inApp.show callback — full control over placement:
synapse("inApp.show", "home_modal", (message) => {
  const handle = renderModal(message, {
    theme: { accent: "#7c3aed" },        // optional --pyrx-ui-* overrides
    onDismiss: (id, reason) => { /* … */ },
    onCtaClick: (id, ctaId) => { /* … */ },
  });
  // handle.element — the mounted root; handle.close() — remove it.
});

Theming

Match your brand in one object

Re-theme per instance with options.theme, or set --pyrx-ui-* CSS variables globally. Overridable tokens: accent, surface, foreground, border, radius, fontFamily, and more. Default accent is the PYRX teal.