Skip to content

Get started

Coras Embed is a JavaScript SDK for ticketing pages. You call mount() with a container, a page name, and config. The SDK renders the page and returns an app handle you use to read state, update the page, and tear it down.

This page gets you from install to a rendered page, then shows the lifecycle methods. For the full options, see the reference pages linked under Next steps.

bash npm install @coras-io/embed
  1. Add a container element to your page:

    <div id="coras"></div>
  2. Mount a page into the container:

    import { mount } from "@coras-io/embed";
    const app = mount({
    container: document.querySelector("#coras")!,
    page: "landing",
    config: {
    apiUrl: "https://sandbox.coras.io",
    distributorId: "a8405267cbcf4bd2b70114e618516645",
    assetsUrl: "https://assets.sandbox.coras.io/shared",
    locale: "en-IE",
    currency: "EUR",
    },
    });
    await app.ready;

mount() returns synchronously and loads the page module in the background. Await app.ready when you need to know that the first render is complete.

For every config field, see the config reference.

After await app.ready resolves, the first render is complete and the page is in the container. Read app.state to confirm the page that mounted:

await app.ready;
console.log(app.state.page); // "landing"

page is one of landing, search, details, payment, or help, plus suggestion-widget - a standalone recommendations embed that is not routable; mount it directly. Each page accepts typed params:

mount({ container, page: "details", config, params: { id: "abc123" } });
mount({ container, page: "search", config, params: { search: "museum" } });

For the params each page accepts, see the pages reference.

Invalid input throws a typed CorasValidationError before anything renders. This includes a missing apiUrl or distributorId, a non-https URL (http is allowed only for localhost), an unsupported locale or currency, and, in strict mode, unknown config or param keys. Each error carries a stable code and a safe message.

Pass strict: true in development so typos in config or param keys fail loudly instead of being silently ignored.

The app handle exposes the methods you use after mounting:

const app = mount(options);
await app.ready; // resolves after the first render
app.state; // frozen snapshot: { page, params, locale, currency }
app.update({ params: { city: "london" } }); // update params in place
app.update({ page: "details", params: { id: "abc123" } }); // change page
app.navigate("payment", { metadata: { orderId: "42" } }); // change page by name
await app.prefetch("payment"); // load a page module ahead of time
app.unmount(); // idempotent teardown
Method Behavior
ready Promise that resolves after the first render. Rejects if the mount is unmounted before it renders.
state Frozen snapshot of the current page, params, locale, and currency.
update(patch) Applies a patch of page, params, config, or chrome. Updates in place unless page changes.
navigate(page, params?, options?) Changes the page by name. Pass { emitNavigate: true } to also emit coras:navigate.
prefetch(page) Loads a page module ahead of time so a later switch renders faster.
unmount() Aborts in-flight loads and removes all SDK DOM, listeners, and timers. Safe to call more than once.

update() avoids remounting unless the page changes. unmount() is safe before, during, and after ready.

By default mount() renders only the page. Opt into the Coras navbar and footer with chrome:

// Both navbar and footer, SDK-managed:
mount({ container, page: "landing", config, chrome: "managed" });
// Per slot. Each accepts false, "managed", an element, or a factory:
mount({
container,
page: "landing",
config,
chrome: { navbar: "managed", footer: false },
});

For navbar feature toggles and host content slots, see the chrome reference.

config.theme sets brand CSS variables scoped to the mounted container, so two mounts on one page can be themed independently:

mount({
container,
page: "landing",
config: {
apiUrl: "https://api.coras.io",
distributorId: "your-distributor-id",
assetsUrl: "https://assets.sandbox.coras.io/shared",
theme: { primary: "#4657d4", secondary: "#161c44" },
},
});

For every theme token, see the theming reference.

Every framework uses the same contract: mount on attach, update() on prop change, unmount() on detach. See Framework integration for copy-paste bindings for React, Next.js, Astro, Vue, Svelte, Solid.js, Angular, Lit, Ember.js, and Alpine.js.