The panels assay dashboard serves are also a web component. A host mounts <assay-dashboard>, hands it a client, and gets spend, sessions, timeline, waste, ROI, and pricing inside its own page — behind its own login, in its own theme. Authentication is always the host’s job. The component never fetches on its own paths. It renders whatever the injected client can answer. A panel exists only if the adapter supplies the matching method.

Smallest mount

A running assay dashboard serves a live copy at /embed. Open it and view source.
<assay-dashboard></assay-dashboard>
<script src="http://127.0.0.1:4319/assets/dashboard.js"></script>
<script>
  const el = document.querySelector('assay-dashboard');
  el.client = AssayDashboard.createRestClient({
    baseUrl: 'http://127.0.0.1:4319',
  });
</script>

Two ways to take the code

ShapeWhen
ESM assay/dashboardThe host already has a bundler
Prebuilt script assay/dashboard/iifeNo bundler, or the app vendors its own copy
The bundle fetches no font, image, or script. It renders with the network unplugged. The Assay mark is inline. Your CSP needs img-src data:.

What the host must not do

  • Do not proxy the loopback console onto the public internet and call that embed. That server has no login.
  • Do not expect the component to hide a panel the adapter still implements. Absence of the method hides the panel.
  • Do not put the content key in the browser. Decrypt on the server the key already lives on. The key never travels; the console does.
Cross-origin: name the origin. A wildcard origin is refused.

Snapshot as an alternative

If you need a packet of pages, not a live mount:
assay dashboard --snapshot ./export
See Dashboard.