Embed Server
A small Node/Express server that serves the embeddable widget. Locally, it runs on http://localhost:3010.
Prerequisites
- Node 22. The Dockerfile, CI and
package.jsonall pin the same major version — keep them in step if you change it.
Run it
cd embed
npm ci
npm run dev
The dev command prepares static assets, builds the widget bundle, and starts the server.
Use npm ci rather than npm install. It installs exactly what package-lock.json pins, which is what CI and the Docker image do.
Routes it serves
| Route | What it is |
|---|---|
/script.js | The widget bundle you just built. Development only — disabled under NODE_ENV=production. |
/healthz | {"ok":true,"version":"…","commit":"…"} for the help pages. |
/ | The help page. |
/privacy | The privacy policy. |
In production the widget is served from a Cloudflare R2 bucket, not by this server, and the versioned URLs (/v1/script.js, /v1.3.0/script.js) exist only there — the dev server has no equivalent of them. See Production → Embed Server.
Pointing a dev site at it
If you're developing a site that embeds the widget (e.g. abair.ie locally), set the widget URL via an env var:
NEXT_PUBLIC_WEBREADER_URL=http://localhost:3010
Restart the framework's dev server after changing it.
Rebuild without restart
| Command | Purpose |
|---|---|
npm run prepare-public | Refresh static assets (help pages, i18n, CSS) |
npm run build | Rebundle the widget into a single minified script |
How the bundle is put together
embed/build.js concatenates the extension's own content scripts, in manifest order, into one IIFE and minifies it. Two things make that work in a page the widget doesn't own:
embed/src/shim.jsprovides achrome.*API — storage, messaging, TTS calls — so the content scripts run unmodified. It is scoped to the bundle, not attached towindow, so it cannot disturb a host site that talks to its own browser extension.embed/src/boot.jsappliesWebReaderConfig, installs the publicwindow.WebReaderAPI, and removes every other global the bundled files publish. OnlyWebReaderandWebReaderConfigare left on the host page.
If you add a file to the content scripts, add it to the FILES array in embed/build.js and to the three manifests, or it will ship in one deliverable and not the other.
Ready to ship? See Production → Embed Server.
Last updated 2026-08-18