@gridd/embeddable-dist
v1.4.0
Published
The built Gridd embeddable app (embeddable.html + assets), self-contained and offline-capable, for hosts that must serve it themselves instead of loading it from a URL
Downloads
167
Maintainers
Readme
@gridd/embeddable-dist
The built Gridd app — embeddable.html and every asset it loads — packaged so a host can serve
it itself instead of fetching it from a URL.
Install this only if your host must work with no network at all. A website or an Office add-in
that loads the app from GRIDD_EMBED_BASE_URL should not install it: it is several megabytes of
app bytes they would download and never execute. That is why it is a separate package rather than a
directory inside @gridd/embed.
Usage
npm install @gridd/embed @gridd/embeddable-distRead the path through @gridd/embed, which is the supported accessor:
const { embeddableDir, assertBuilt } = require("@gridd/embed/embeddable-path");
assertBuilt(); // throws with instructions if the package was installed unbuilt
const dir = embeddableDir(); // serve this directory as static files, on its own loopback portThis package's own entry point exposes the same values directly, if you would rather not depend on
@gridd/embed in your main process:
const { embeddableDir, embeddablePath, version, builtAt, assertBuilt } = require("@gridd/embeddable-dist");version is the app build stamp (e.g. beta-1.0.20260825.084937), read from version.json beside
the bundle — not this package's semver. That is the number to show in About and stamp on decks:
offline there is no server to reconcile a deck edited against one build and reopened against
another.
Serving it
- Serve the directory at a path root and return
embeddable.htmlfor/. Asset URLs are relative and resolved at runtime from the script's own URL, so any port or scheme works — but a rewritten path prefix or an injected<base>tag will break it, and the symptom is a silently blank iframe. - Serve it from a different origin than your host page. Edits reach the host over postMessage, and that bridge only activates when the iframe is cross-origin. Two loopback ports is enough.
- A loopback host origin is trusted to run an editable embed by rule, so no allowlist entry is needed. See Editable origins.
Guarantees
The build makes zero runtime network requests: no web fonts, no analytics, no license or feature-flag check. Web fonts matter more than they sound — a Google Fonts fetch that fails offline changes text metrics, and a deck laid out on a fixed logical canvas then exports to a different PDF.
npm run build:embeddable-dist in the Gridd repo produces this directory and then fails the build
on a reintroduced beacon host, a remote @font-face, a root-relative or absolute asset URL, a
hardcoded webpack public path, or a missing version.json.
Building
npm run build:embeddable-dist # build + static audit
npm run verify:offline # automated: renders, editable, edit pushes back, all assets local
npm run verify:online # the same protocol check against the dev server (regression guard)
npm run serve:embeddable-dist # manual: two loopback servers + a harness page for the DevTools passverify:offline starts two loopback servers — the app on one port, a host page implementing the
protocol on another — and drives them with Chrome. It fails if the grid does not render, if the
embed falls back to read-only, if no edit reaches the host, or if any asset 404s. verify:online
runs the identical check against https://localhost:3000, so a packaging change that breaks the
hosted app is caught in the same command.
dist/embeddable/ is generated and not committed. Installing this package from a git checkout
without building it leaves assertBuilt() to throw with instructions rather than letting a host
serve an empty directory.
