2.8 KiB
html/render-shell — Altair HTML shell builder
(no submodules)
Purpose
html/render-shell produces the single HTML document the Altair UI
plugin serves at <uiEndpoint>. The shell mounts a <div id="altair-root">,
embeds the resolved JS/CSS asset URLs (hash-busted, so CDN cache
behaviour is correct), and serialises the parsed AltairUiOptions as a
<script type="application/json"> data block — never as executable
inline JavaScript — so the strict CSP attached by headers/csp can
forbid script-src 'unsafe-inline' outright.
Features
- One self-contained HTML document — no external host references.
- Configurable endpoints surfaced both as
<meta>tags AND asdata-*attributes on the root container, so consumers integrating Altair via custom JS can read either layer. - JSON config block escaped against
</script>injection per the HTML5 spec recommendation. - User-supplied endpoint values HTML-escaped before embedding.
- Theme attribute (
data-altair-theme) on<html>for CSS hooks.
Usage: Basic
import { renderAltairShell } from "@suaveplan/api-graphql-ui-altair/html";
import { buildDefaultAssetRegistry } from "@suaveplan/api-graphql-ui-altair/assets";
import { parseAltairUiOptions } from "@suaveplan/api-graphql-ui-altair/options";
const html = renderAltairShell({
options: parseAltairUiOptions(),
assetRegistry: buildDefaultAssetRegistry(),
});
Usage: Advanced
import { renderAltairShell } from "@suaveplan/api-graphql-ui-altair/html";
import {
buildDefaultAssetRegistry,
defineAsset,
} from "@suaveplan/api-graphql-ui-altair/assets";
import { parseAltairUiOptions } from "@suaveplan/api-graphql-ui-altair/options";
const registry = new Map(buildDefaultAssetRegistry());
registry.set(
"logo.svg",
defineAsset("logo.svg", "image/svg+xml", "<svg/>")
);
const html = renderAltairShell({
options: parseAltairUiOptions({
theme: "dark",
initialEnvironments: {
production: { url: "https://api.example.com/graphql" },
},
}),
assetRegistry: registry,
});
API Reference
RenderAltairShellInput—{ options: AltairUiOptions; assetRegistry: ReadonlyMap<string, BundledAsset> }.renderAltairShell(input): string— returns the full HTML document including the<!DOCTYPE html>declaration.
Implementation Notes
The </script> escape inside the JSON config block uses the HTML5
spec's recommended sequence <\/script so the JSON itself remains
parseable while the closing-tag-injection vector is closed. All
user-supplied strings flowing into HTML attributes pass through a
four-character HTML escape — the structural goal is "no inline script
ever executes", which the strict CSP then enforces at the browser.