@enviera/sidecar
v0.1.0
Published
Client loader for the Enviera sidecar (staging feedback widget). Framework-agnostic core plus a React adapter; Svelte and Vue adapters are planned on the same core.
Readme
@enviera/sidecar
Typed client loader for the Enviera sidecar. The sidecar mounts on every page of an embedding app — eagerly, before any login — and capabilities activate on top of it:
- Feedback (built, lazy): reviewers on a staging site click the feedback button, click any element, and type a note — it lands as a labeled GitHub issue in the project's issue repo, with page URL, element, and reporter identity. Dormant until the app hands over the signed-in user.
- Monitoring / analytics (planned, eager): identity-free capabilities driven by per-project remote configuration.
The widget itself is a hosted script (served by the sidecar worker); this package configures and lazily injects it, so every embedding app runs the same, always-current version.
Identity: optional to mount, required for feedback
Mount the sidecar everywhere, immediately — no identity needed. The
feedback capability arms only once setIdentity provides the signed-in
user, and both email and name are mandatory there: embedding apps have
their own login, and a feedback issue without a reporter is not actionable
for triage. There is no anonymous feedback mode.
The identity is display-level: the created issue marks it "(unverified)" unless a trusted gateway identity vouches for the request server-side.
React
import { Sidecar } from "@enviera/sidecar/react";
function AppSidecar() {
const { user } = useYourAuth(); // null while the session resolves
if (process.env.NEXT_PUBLIC_FEEDBACK_WIDGET !== "on") return null;
return (
<Sidecar
project="your-project-id"
identity={user ? { email: user.email, name: user.name } : undefined}
/>
);
}The component renders nothing. Mount it on every page (inside your auth
provider); pass identity={undefined} while the session resolves — the
feedback capability arms itself once both fields are present. Only render
on environments where the sidecar belongs (staging — never production,
until an eager monitoring capability changes that calculus).
Vanilla JavaScript
The root export is the framework-agnostic core the adapters build on:
import { initSidecar } from "@enviera/sidecar";
const sidecar = initSidecar({ project: "your-project-id" });
// later, once your session resolves:
sidecar.setIdentity({ email: session.email, name: session.name });initSidecar is idempotent per page (one sidecar; repeat calls return the
same handle), throws a TypeError on a missing project, and safely no-ops
during server-side rendering. setIdentity throws when either field is
missing, and is a one-way switch — arming is per-page-load.
Architecture / planned adapters
core (this package's root export — init, identity handoff, capability arming)
├── capabilities:
│ feedback — built (lazy: arms on setIdentity)
│ monitoring — planned (eager, identity-free, remote-configured)
└── adapters, one subpath export each:
./react — built
./svelte — planned (same shape: mount eagerly, hand identity later)
./vue — plannedAdapters stay thin: mount the core in their framework's lifecycle and pass identity through when the app knows it. New adapters should not add behavior beyond that.
Prerequisites for a new project
- The project must have a row in the studio project registry (issue repo + allowed staging origins).
- The feedback GitHub App must have access to the project's issue repo.
- Your staging origin must be in that registry row's allowed origins — requests from other origins are refused server-side.
