#Sigil (telemetry & feedback)
@alepha/sigil wires a Lore Sigil into an Alepha
app: cookieless pageview analytics (beacon), Web-Vitals p75, client &
server error capture (blights), and a floating feedback button that
opens the Lore petition page (petition) — all behind one module import.
The package is private (vendor-only) and targets Alepha React apps. It replaces the legacy
<script src=".../embed.js">snippet.
#How it works
The sigil UUID is a server-only secret — it never reaches the browser.
The module ships server code into your app that exposes a same-origin proxy
(/api/sigil/*); the browser posts telemetry to that proxy, and your server
forwards it to Lore over a server-to-server call authenticated solely by the
secret UUID. No ingestKey, no CORS, no Origin/UA gates.
browser ──(same-origin)──▶ /api/sigil/ingest ──(server→server, secret UUID)──▶ lore.alepha.dev
Telemetry is mutualized: pageviews, client errors, and vitals are batched
into a single ingest call (flushed on a timer + pagehide).
Petitions are first-party: the feedback button does a synchronous
window.open("/sigil/request"); that same-origin proxy resolves the
sigil → campaign id server-side (via GET /sigils/:id/campaign) and
302-redirects to the Lore petition page {loreOrigin}/c/:campaignId/request,
which requires login. The sigil id never reaches the browser, and petitions
have no DB relation to the sigil.
#Setup
One step, plus env.
1. Import the module in your web module:
1import { $module } from "alepha";2import { AlephaSigil } from "@alepha/sigil";3 4export const WebModule = $module({5 name: "myapp.web",6 imports: [AlephaSigil],7});
2. Set the env (server-only):
| Var | Required | Notes |
|---|---|---|
SIGIL_ID |
to enable | The sigil UUID. A server-only secret — never prefix with VITE_. |
LORE_URL |
no | Override the Lore origin (default https://lore.alepha.dev). |
#Activation
Sigil is active only when alepha.isProduction() and SIGIL_ID is set.
In development it is silently inert. In production without SIGIL_ID it logs a
gentle warning and stays disabled (no fail-fast). The floating feedback button
auto-mounts on every page via the framework's RootComponentsProvider slot —
you don't place any JSX, and there is no stylesheet to import (the button is
inline-styled).
#What each capability needs
The telemetry capabilities (beacon / blights / vitals) are gated on the
Lore side by the campaign's feature flags and the sigil's kinds; the module
sends everything it can and Lore ignores capabilities a given sigil hasn't
enabled. The petition button just opens the campaign's first-party request
page, which enforces login and the campaign's petitions feature itself.
#Privacy
No cookies, no client-supplied identity. Country + a daily-rotating, non-reversible visitor hash are derived server-side (in your app, from its own edge) and forwarded — Lore never sees a raw IP. Error stacks are truncated and query strings stripped.