Vanilla JS
Use the <audit-trail> custom element from @everscribe/components-element to embed the audit-trail UI in plain HTML. No framework, no bundler. The element registers itself globally on import; the tag works anywhere HTML does.
Source: packages/element
Install
Two ways: via npm (if you have a bundler) or via a script tag (if you don't).
npm
npm install @everscribe/components-element @everscribe/components-styles
import "@everscribe/components-element";
import "@everscribe/components-styles/default.css";
Script tag
<link rel="stylesheet" href="https://unpkg.com/@everscribe/components-styles/default.css">
<script type="module">
import "https://unpkg.com/@everscribe/components-element";
</script>
The element registers itself as <audit-trail> on import. The import is idempotent. Safe to include in multiple bundles.
Quickstart
<audit-trail token-endpoint="/api/embed-token"></audit-trail>
token-endpoint is a route on your server (not Everscribe's) that returns { token }. The element fetches it on mount, holds it in memory, and re-fetches on 401. Your project API key never touches the browser. See Overview → Minting tokens for the backend side.
If you have a token already, pass it directly:
<audit-trail token="eyJhbGciOi..." token-endpoint="/api/embed-token"></audit-trail>
Pass token-endpoint alongside token so refresh on 401 still works.
Custom auth header on the token fetch
The built-in token-endpoint fetcher POSTs with credentials: 'include' and no body. No custom headers. If your endpoint needs an extra header (CSRF, tenant ID, bearer), use the JS-only onTokenExpired property:
const el = document.querySelector("audit-trail");
el.onTokenExpired = async () => {
const res = await fetch("/api/embed-token", {
method: "POST",
credentials: "include",
headers: { "X-Tenant": currentUser.tenantId },
});
const { token } = await res.json();
return token;
};
onTokenExpired is invoked both for the initial token fetch (when the token attribute is unset) and on every 401 refresh.
Attributes
At least one of token, token-endpoint, or the JS-only onTokenExpired property is required.
| Attribute | Type | Default | Notes |
|---|---|---|---|
token |
string | — | Embed JWT. If omitted, the element fetches one via token-endpoint/onTokenExpired on mount. |
token-endpoint |
string | — | URL on your backend returning { token }. Used for the initial fetch and for refresh on 401. POSTed with credentials: 'include' and no body, so register the route for POST. |
api-base |
string | https://api.everscribe.io/v1/embed |
Base URL for read endpoints. Override for local dev or self-hosted. |
page-size |
number | 25 |
Events per page. |
poll-interval |
number | 5000 |
Poll cadence in ms. <= 0 disables polling. Below 1000 is clamped with a console.warn. |
theme |
light | dark |
light |
Switches the CSS-variable theme. |
default-time-range |
24h | 7d | 30d | all |
all |
Initial time-range preset (read at mount only). |
Style and class come from the standard class and style attributes. The element renders into its own light DOM, so the CSS from @everscribe/components-styles/default.css applies the same way it does for the React component.
Properties and methods (JS only)
These can't be expressed as attributes; set them on the element directly via JS.
| Property | Type | Notes |
|---|---|---|
onTokenExpired |
() => Promise<string> |
Custom token-fetch callback. Takes precedence over token-endpoint. |
refresh() |
() => void |
Public method. Triggers a full re-bootstrap (fresh token fetch + fresh stores). |
Events
| Event | detail |
Notes |
|---|---|---|
audit-trail-error |
{ error: Error } |
Bubbles. Fired on fetch errors that surface from the events store (network, server, expired token after the refresh chain is exhausted). |
document.querySelector("audit-trail").addEventListener("audit-trail-error", (e) => {
console.error(e.detail.error);
});
Persistence
Column visibility and filter state persist to localStorage automatically and restore on reload. Same keys and behavior as the React adapter. They're shared between adapters, so customers using both under the same origin share state cleanly.
Vue, Solid, Angular
The same @everscribe/components-element package works in Vue, Solid, and Angular. Vue and Solid template syntax supports custom-element events via @audit-trail-error and on:audit-trail-error respectively. For React, prefer @everscribe/components-react. React 18's custom-element interop has known rough edges around prop conventions and synthetic events.