Deploying to a host app
Two script tags. The host app stays untouched. CSP, identity probes, rollback covered.
1. Register the host app
Add an entry under Portfolio. The Observer fetches its profile from /registry/v1/profile?domain=<host> on every page load (cached 5 minutes in sessionStorage).
2. Drop the two script tags into the host app
<!-- in the host app's <head> -->
<script src="https://observer.hexalab.dev/observer.iife.js"
data-app-id="elyxen"
data-registry-url="https://observer.hexalab.dev"
async></script>
<script src="https://observer.hexalab.dev/injector.iife.js"
data-injector-auto
async></script>Both bundles are self-booting when the data-app-id / data-injector-auto attributes are present. Loading order doesn't matter — the Injector waits for help:content events.
3. Stay silent first
The seeded app profile defaults to observerEnabled: false. The Observer bundle loads, detects the framework, reads identity — and emits nothing. This is the safety net. You can ship the script tags to production today and go live per-app on your own schedule.
Verify the silent boot in DevTools:
window.addEventListener('help:ready', e => console.log('ready', e.detail));
// You should see one event with appId + observerVersion + hostOrigin.4. Identity probe (MSAL example)
The Observer auto-detects which auth provider the host app uses. To verify it found yours, in DevTools:
// For MSAL apps:
Object.keys(sessionStorage).filter(k => k.startsWith('msal'))
// Should return at least one key. If empty, check localStorage instead.
// The Observer probes both.If identity.jurisdiction comes back null, decide whether to add a jurisdiction claim to your JWT (preferred) or fall back to app.jurisdictions[0] (already supported — no action needed).
5. Content Security Policy
Strict script-src without unsafe-inline will block the bundles unless you:
- Host the bundles on the same origin as the host app, or
- Add the help-layer origin to
script-src, or - Use Subresource Integrity (recommended for compliance apps — pin a SHA-384 hash).
6. Go live for one app
7. Tooltip conflicts
If the host app uses Angular Material / Material UI / a similar component library, its own tooltips may compete for the same field. The Injector listens for mdc-tooltip-show and similar lifecycle events and yields by default. Override with:
HelpInjector.boot({
// 'yield' (default) — defer to the host's tooltip
// 'replace' — hide the host's tooltip while ours is open
// 'coexist' — show both
conflictPolicy: 'yield',
});Rollback
The Observer ships zero changes to the host app's DOM, code, or build pipeline. To roll back: remove the two <script> tags. There is nothing else to undo. No migrations to reverse, no cache to flush, no state to clean up.
If you can't deploy a new build immediately, flip observerEnabled to false in the registry. Live Observers will see the change within 5 minutes and go silent.
docs/deploy-to-host-app.md for the full markdown version (committed to git, no console required).