Configuration
Heimdall has two configuration surfaces: server registration settings and the browser runtime object exposed as window.Heimdall.
Use this page when you need the exact defaults, the mutable runtime properties, and the timing rules for when a setting must be applied.
1. Configuration Surfaces
Most application configuration happens on the server. Browser behavior that is intentionally runtime-tunable lives under Heimdall.config after the JavaScript bundle loads.
Server:
builder.Services.AddHeimdall(options => { ... });
app.UseHeimdall();
Browser:
window.Heimdall
window.Heimdall.config2. Server Settings
AddHeimdall accepts HeimdallServiceSettings. These settings affect server endpoint behavior, error detail, and Bifrost topic authorization.
builder.Services.AddHeimdall(options =>
{
options.EnableDetailedErrors = builder.Environment.IsDevelopment();
options.BifrostTopicPolicy = "BifrostTopic";
options.AuthorizeBifrostTopic = (ctx, topic) =>
ValueTask.FromResult(topic.StartsWith("user:"));
options.BifrostHeartbeatInterval = TimeSpan.FromSeconds(15);
});3. Server Defaults
These are the framework defaults from HeimdallServiceSettings.
EnableDetailedErrors:
false
BifrostTopicPolicy:
null
AuthorizeBifrostTopic:
null
BifrostHeartbeatInterval:
15 seconds4. Browser Runtime Object
After the bundle loads, Heimdall assigns a global runtime object to window.Heimdall. Its methods are the supported browser-side API surface.
Heimdall.apiVersion
Heimdall.invoke(actionId, payload, options)
Heimdall.boot(root)
Heimdall.onReady(callback)
Heimdall.clearCsrfToken()
Heimdall.sse.connect(topic, options)
Heimdall.sse.disconnect(element)
Heimdall.sse.disconnectAll()
Heimdall.config
Heimdall._observerOOB Default
Out-of-band response directive processing is enabled by default. The runtime default is Heimdall.config.oobEnabled = true. Set it to false only when the application wants to ignore <invocation> directives returned by actions or SSE payloads.
5. Set Runtime Config
The runtime creates Heimdall.config when the script loads. Put configuration immediately after the runtime script, and put early-boot options before DOMContentLoaded or before any manual boot call.
<script src="/_content/HeimdallFramework.Web/heimdall-bundle.min.js"></script>
<script>
Heimdall.config.debug = true;
Heimdall.config.inputDebounceMs = 350;
Heimdall.config.hoverDelayMs = 200;
Heimdall.config.oobEnabled = true;
</script>6. Runtime Config Defaults
These are the current browser runtime defaults from startup.js.
Heimdall.config = {
basePath: "/__heimdall",
apiVersion: 1,
endpoints: {
contentActions: "/__heimdall/v1/content/actions",
csrf: "/__heimdall/v1/csrf",
bifrostToken: "/__heimdall/v1/bifrost/token",
bifrost: "/__heimdall/v1/bifrost"
},
observeDom: true,
debug: false,
inputDebounceMs: 250,
hoverDelayMs: 150,
scrollThresholdPx: 120,
scrollMinIntervalMs: 250,
visibleRootMargin: "0px",
visibleThreshold: 0,
oobEnabled: true,
sseDefaultSwap: "none",
sseEventName: "heimdall",
sseReconnectDelayMs: 250,
sseReconnectMaxDelayMs: 10000,
sseReconnectBackoffFactor: 2,
sseSweepIntervalMs: 5000,
ssePauseWhenHidden: false
};7. Endpoint Configuration
Endpoint values are read when the runtime makes a request. The default paths match app.UseHeimdall(). Only change them when the server has been mapped behind a matching path or proxy.
Heimdall.config.endpoints.contentActions = "/internal/heimdall/actions";
Heimdall.config.endpoints.csrf = "/internal/heimdall/csrf";
Heimdall.config.endpoints.bifrostToken = "/internal/heimdall/bifrost/token";
Heimdall.config.endpoints.bifrost = "/internal/heimdall/bifrost";Content actions send POST requests with the action id in the query string and X-Heimdall-Content-Action header. CSRF and Bifrost token requests are same-origin GET requests.
8. Trigger Timing Defaults
These config values supply runtime defaults. Per-element attributes still win when they are present on the DOM element.
Heimdall.config.inputDebounceMs
-> default for heimdall-content-input
-> overridden by heimdall-debounce
Heimdall.config.hoverDelayMs
-> default for heimdall-content-hover
-> overridden by heimdall-hover-delay
Heimdall.config.scrollThresholdPx
-> near-end scroll distance
-> overridden by heimdall-scroll-threshold
Heimdall.config.scrollMinIntervalMs
-> minimum time between scroll-triggered actions9. Boot and DOM Observation
The runtime boots document boundaries on ready. observeDom installs a MutationObserver so newly inserted Heimdall markup is activated automatically.
Heimdall.config.observeDom = true;
// Manual boot is useful when observeDom is false,
// or when an external renderer inserts markup.
Heimdall.boot(document.querySelector("#new-region"));10. Visible Trigger Timing
visibleRootMargin and visibleThreshold are read once when the IntersectionObserver is first created. Set them before visible elements are booted.
<script src="/_content/HeimdallFramework.Web/heimdall-bundle.min.js"></script>
<script>
Heimdall.config.visibleRootMargin = "200px 0px";
Heimdall.config.visibleThreshold = 0.1;
</script>11. OOB Configuration
OOB processing controls whether returned invocation directives can update other DOM regions outside the main target. Redirect and abort directives are still response directives, but invocation processing is gated by oobEnabled.
// Default: true
Heimdall.config.oobEnabled = true;
// Disable invocation directive processing.
Heimdall.config.oobEnabled = false;12. SSE Configuration
Bifrost SSE uses global defaults for event name, default swap mode, reconnect behavior, sweep timing, and hidden-tab pause behavior. Subscriber attributes can override event, target, swap, and disable behavior per element.
Heimdall.config.sseDefaultSwap = "none";
Heimdall.config.sseEventName = "heimdall";
Heimdall.config.sseReconnectDelayMs = 250;
Heimdall.config.sseReconnectMaxDelayMs = 10000;
Heimdall.config.sseReconnectBackoffFactor = 2;
Heimdall.config.sseSweepIntervalMs = 5000;
Heimdall.config.ssePauseWhenHidden = false;Per-subscriber HTML attributes:
heimdall-sse="orders"
heimdall-sse-topic="orders"
heimdall-sse-target="#orders"
heimdall-sse-swap="beforeend"
heimdall-sse-event="order.updated"
heimdall-sse-disable="true"13. Programmatic Invocation
Use Heimdall.invoke when a browser script needs to run the same content-action request pipeline as a DOM trigger.
const result = await Heimdall.invoke(
"orders.refresh",
{ page: 2 },
{
target: "#orders",
swap: "inner",
headers: { "X-Request-Source": "toolbar" },
onSuccess: result => console.log(result.ms),
onError: result => console.warn(result.status)
});14. Programmatic SSE
Use Heimdall.sse.connect when a script needs to subscribe without a declarative heimdall-sse attribute. The element anchors lifecycle validation for that subscription.
const subscription = Heimdall.sse.connect("orders", {
element: document.querySelector("#orders-panel"),
target: "#orders",
swap: "beforeend",
event: "order.updated"
});
subscription.close();
Heimdall.sse.disconnect("#orders-panel");
Heimdall.sse.disconnectAll();15. Runtime Events
The runtime emits CustomEvent notifications on document. Turn on debug for console traces, and use events when application code needs observability around Heimdall work.
Heimdall.config.debug = true;
document.addEventListener("heimdall:before", e => {});
document.addEventListener("heimdall:after", e => {});
document.addEventListener("heimdall:error", e => {});
document.addEventListener("heimdall:abort", e => {});
document.addEventListener("heimdall:redirect", e => {});
document.addEventListener("heimdall:javascript-error", e => {});
document.addEventListener("heimdall:sse-open", e => {});
document.addEventListener("heimdall:sse-close", e => {});
document.addEventListener("heimdall:sse-message", e => {});
document.addEventListener("heimdall:sse-error", e => {});
document.addEventListener("heimdall:sse-pause", e => {});
document.addEventListener("heimdall:sse-resume", e => {});
document.addEventListener("heimdall:sse-reconnect-scheduled", e => {});
document.addEventListener("heimdall:sse-abort", e => {});
document.addEventListener("heimdall:sse-redirect", e => {});16. When Changes Take Effect
Most values are read at the moment of use. A few bootstrapping values need to be set early because observers and sweep timers are created once.
Read on each request:
endpoints, debug, oobEnabled
Read from each trigger event:
inputDebounceMs, hoverDelayMs,
scrollThresholdPx, scrollMinIntervalMs
Set before first visible boot:
visibleRootMargin, visibleThreshold
Set before ready for automatic DOM observing:
observeDom
Set before SSE starts for initial sweeper interval:
sseSweepIntervalMs
Read during SSE reconnect/pause behavior:
sseReconnectDelayMs, sseReconnectMaxDelayMs,
sseReconnectBackoffFactor, ssePauseWhenHidden17. Practical Defaults
For most apps, keep the default endpoints, keep observeDom on, keep OOB on, and tune only the user-experience timings that your UI actually needs.
Common application-level tweaks:
Heimdall.config.debug = builderEnvironmentIsDevelopment;
Heimdall.config.inputDebounceMs = 300;
Heimdall.config.hoverDelayMs = 250;
Heimdall.config.ssePauseWhenHidden = true;Next Steps
After configuration, the most useful references are the raw HTML attribute surface, the runtime behavior model, and the security boundaries around response processing.