Embed Without a Framework
createEmbed from @nexatron/chat/embed (SDK 0.8.0) puts a dashboard or one saved answer in any web page. It needs no framework, gives the host typed events and commands, and asks the host for a fresh token before the current one expires, so a page left open keeps working without reloading the iframe.
For a chat surface in a React app, use the React quickstart instead.
Not on npm yet.
@nexatron/chatis not published to the npm registry. Ask support for the release tarball and install that file.
npm install ./nexatron-chat-0.8.0.tgz
The tarball also carries a one-script build, dist/nexatron-embed.global.js, which exposes the same functions on the global NexatronEmbed.
Embed a dashboard
import { createEmbed, sessionTokenProvider } from '@nexatron/chat/embed';
const embed = createEmbed({
el: document.getElementById('board'),
kind: 'dashboard', // or 'answer'
id: 'dashboard-uuid',
tenantId: 'workspace-uuid',
baseUrl: 'https://nexatron.io',
// Your backend signs a short assertion for the signed-in user; the provider
// exchanges it for an embed token and tells the SDK when it expires.
getToken: sessionTokenProvider({
apiUrl: 'https://nexatron.io/api/v1',
getAssertion: () => fetch('/my-backend/nexatron-assertion').then((r) => r.text()),
}),
});
embed.on('drill', ({ column, value }) =>
embed.setFilters([{ id: column, label: column, values: [value] }]),
);
getToken may be any function returning a token, or { token, expiresAt }. It is called at start and again shortly before each token expires.
Options
| Option | Meaning |
|---|---|
el | The element the iframe is appended to. |
kind | dashboard (default) or answer. |
id | The dashboard or answer id. |
tenantId | The workspace id. With it the embed loads from the workspace-scoped address, framed only by the origins the workspace allows. Required for an answer. |
baseUrl | The Nexatron web origin. Must be an absolute https URL (http for localhost only). |
getToken | Returns the embed token. |
filters, tab | Filters and dashboard tab for the first render. |
theme | --nexatron-* CSS properties applied over the workspace's embed theme. |
locale | The reader's locale, for example de-DE. |
autoResize | Size the iframe to its content. Default true. |
height | Initial iframe height, or the fixed height without autoResize. Default 600px. |
title | Accessible title of the iframe. |
refreshBeforeExpirySeconds | How long before expiry to ask for a new token. Default 60. |
Events
embed.on(name, handler) returns a function that unsubscribes.
| Event | Payload | When |
|---|---|---|
ready | none | The page is up and asked for its token. |
load | { kind, id } | The dashboard or answer rendered. |
filterChange | { filters } | The board re-rendered with filters from setFilters. |
tabChange | { tab } | The reader or setTab switched tabs. |
drill | { tileId, column, value } | The reader picked a mark. |
resize | { height } | The content height changed. |
error | { code, message } | Something went wrong; code is stable, message is for people. |
Commands
| Command | Effect |
|---|---|
setFilters(filters) | Re-render with these filters. |
refresh() | Reload the data. |
setTab(tab) | Switch dashboard tab. |
setTheme(theme) | Apply theme properties. |
rotateToken() | Ask getToken for a new token now. |
destroy() | Remove the iframe and stop token rotation. |
Security
- Messages go only to the embed's own origin, derived from
baseUrl, and are accepted only from that iframe's window at that origin. There is no"*"fallback: abaseUrlthat is not a valid URL throwsEmbedConfigError. - The token never appears in the iframe's
src. It is delivered bypostMessageafter the page says it is ready. - The signing secret stays on your backend. Never ship it to the browser.