Runtime Contract

JavaScript Runtime

The generator keeps Hugo-rendered HTML as the source of truth and adds behavior through small CDN scripts. Shared browser behavior lives under window.QL.

Runtime Surface

  • window.QL.layout.ready() waits for DOM readiness, stylesheet settlement, fonts when available, and one animation frame.
  • window.QL.layout.whenReady(fn, { scope }) runs first-paint layout work after the page is safe to measure.
  • window.QL.layout.schedule(name, fn, { phase, priority }) coalesces layout tasks. Prefer layout-read for measurement and layout-write for CSS/DOM writes.
  • window.QL.layout.observePersistent(selector, fn) observes persistent chrome that may be replaced during SPA navigation.
  • window.QL.runtime.register({ name, selector, init }) is the preferred shape for new DOM components. Existing window.QlWidgetRuntime helpers remain supported as compatibility aliases.
  • Set window.QL.debug = true on local/dev hosts to log slow layout tasks, slow component initialization, and duplicate component registration.

Migration Rules

  • Do not read layout during initial script execution or raw DOMContentLoaded. Use QL.layout.whenReady.
  • Keep pointer, resize, and animation-frame measurements local when they are already user-driven or frame-driven.
  • Keep Nowtype/PDF pagination domain-owned. The shared layout runtime may trigger editor refreshes, but it must not replace editor-specific measurement, typing suppression, focus restoration, or overlay positioning.
  • New SPA-aware widgets should consume QL.runtime and the existing SPA events through the runtime instead of creating another lifecycle vocabulary.

Smoke Test

Run npm run browser:smoke:js-runtime -- <origin> against a running local site. The smoke asserts that the shared runtime exists, SPA navigation works, local prefetches do not fail, PhotoSwipe opens when present, and layout-related console warnings do not recur.