React

@everscribe/components-react is the React adapter for the embeddable audit-trail UI. <AuditTrail /> mounts in any React 18+ app and renders a live, scoped view of your end-user's audit trail.

Source: packages/react

Install

npm install @everscribe/components-react @everscribe/components-styles

Peer dependencies: react >=18, react-dom >=18. The styles package ships the default CSS theme — install it alongside.

Quickstart

import { AuditTrail } from "@everscribe/components-react";
import "@everscribe/components-styles/default.css";

export function AuditPage() {
    return <AuditTrail tokenEndpoint="/api/embed-token" />;
}

tokenEndpoint is a route on your server (not Everscribe's) that returns { token }. The component fetches it on mount, holds it in memory, and re-fetches from the same endpoint on 401. Your project API key never touches the browser. See Overview → Minting tokens for the backend side.

If your React app and backend share an origin, a relative path (/api/embed-token) works too.

Already have a token

If you'd rather control the initial fetch yourself — explicit loading states, integration with an auth context, or a token already in hand — pass it as the token prop:

import { useEffect, useState } from "react";
import { AuditTrail } from "@everscribe/components-react";
import "@everscribe/components-styles/default.css";

export function AuditPage() {
    const [token, setToken] = useState<string | null>(null);

    useEffect(() => {
        fetch("/api/embed-token", { credentials: "include" })
            .then((r) => r.json())
            .then(({ token }) => setToken(token));
    }, []);

    if (!token) return <div>Loading</div>;
    return <AuditTrail token={token} tokenEndpoint="/api/embed-token" />;
}

Pass tokenEndpoint (or onTokenExpired) alongside token so refresh on 401 still works.

If you pass none of token, tokenEndpoint, or onTokenExpired, the component renders a configuration error.

Props

At least one of token, tokenEndpoint, or onTokenExpired is required.

Prop Type Default Notes
token string Embed JWT. If omitted, the component fetches one via tokenEndpoint/onTokenExpired on mount.
tokenEndpoint string URL on your backend returning { token }. Used for the initial fetch (when token is omitted) and for refresh on 401. Sent with credentials: 'include'.
onTokenExpired () => Promise<string> Custom token-fetch callback. Takes precedence over tokenEndpoint.
apiBase string https://api.everscribe.io/v1/embed Base URL for read endpoints. Override for local dev or self-hosted.
pageSize number 25 Events per page.
pollInterval 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.
defaultTimeRange '24h' | '7d' | '30d' | 'all' 'all' Initial time-range preset for the filters panel.
className string Merged onto the root element.
style CSSProperties Inline style on the root. Use to override CSS variables at runtime.
onError (err: Error) => void Observability hook for fetch errors.

Persistence

Column visibility and filter state persist to localStorage automatically and restore on mount. Two keys are written, both namespaced by the token's project ID (sub claim) and tenant ID (tenant_id claim, or _ when unset):

  • audit-trail:cols:{sub}:{tenant_id} — list of hidden columns. Stored as hidden so future-added columns appear by default for returning users.
  • audit-trail:filters:{sub}:{tenant_id} — active filter state: time range, column filters, free-text inputs, DSL query, last NLP echo.

Behavior:

  • Restored once the token bootstrap resolves and the JWT is parsed.
  • Swapping the token prop to a different project re-restores from that project's storage.
  • localStorage failures (private browsing, quota exceeded, malformed JSON) are silently swallowed.
  • Token claims that restrict columns (columns claim set) take precedence over restored hidden columns.

SSR / Next.js

Marked 'use client' — drop into a Server Component tree as-is. The detail drawer portals to document.body after hydration; persistence useEffects only fire client-side, so they have no SSR side effects.

What next

  • Overview — token model, refresh chain, claim-driven UI, rate limits
  • Styles — theming via CSS variables
  • Embed Tokens — the security model