WORK-293
Setting up your dashboard 0 entities found · 9/32 branches scanned
ID:WORK-293Status:review

Ship the client behaviors bundle in the html scaffold

The @refrakt-md/html scaffold (create-refrakt template-html) emits static HTML with no client JSbuild.ts never bundles or references initPage() from @refrakt-md/html/client. So no interactive behavior runs in a scaffolded html site: tabs, accordion, search, and (since SPEC-073) the theme-toggle button are all inert. The adapter ships the client runtime (@refrakt-md/html/client + @refrakt-md/behaviors); the scaffold just never bundles and includes it.

Discovered while finishing WORK-292: the html adapter now injects the no-flash pre-paint script (which works without JS), but the toggle can't cycle until the behaviors bundle loads. This is broader than the toggle — it's the html scaffold's general interactivity gap.

Priority:mediumComplexity:moderateMilestone:v0.20.2Source:SPEC-073
changeset-release/main View source

Criteria completion

Criteria completion: 3 of 4 (75%) checked; history from Jun 2 to Jun 110%25%50%75%100%Jun 2Jun 11
Branches 7
History 8
  1. 3ddc279
    • ☑ `template-html`'s build produces a client bundle that calls `initPage()` from `@refrakt-md/html/client` (e.g. an esbuild/rollup step over a small entry, output to `build/`).
    • ☑ `build.ts` references the bundle via `renderFullPage`'s `scripts` option so every page loads it.
    • ☑ Layout chrome CSS (header/search/theme-toggle) is shipped by the scaffold so the controls are styled, not just present.
    by github-actions[bot]
  2. 19c9bd5
    Content editedby github-actions[bot]
  3. ca722d4
    Content editedby github-actions[bot]
  4. da5f6f0
    Created (ready)by github-actions[bot]
  5. 2d85b5f
    Content editedby Claude
    chore: prep v0.17.0 release — changeset, milestone, defer 293/296
  6. e5b9dc6
    Content editedby Claude
    plan: close v0.16.0, open v0.17.0, defer WORK-293 + WORK-296
  7. 3b2a7c3
    Content editedby Claude
    plan: SPEC-075 — comparable attribute types (typed sort + validation)
  8. bb33e35
    Content editedby Claude
    plan: WORK-293 — ship the client behaviors bundle in the html scaffold

Acceptance Criteria

  • template-html's build produces a client bundle that calls initPage() from @refrakt-md/html/client (e.g. an esbuild/rollup step over a small entry, output to build/).
  • build.ts references the bundle via renderFullPage's scripts option so every page loads it.
  • A scaffolded html site has working interactive runes — verified with at least the theme-toggle (cycles auto→light→dark) and one other behavior (e.g. tabs or search) in a browser.
  • Layout chrome CSS (header/search/theme-toggle) is shipped by the scaffold so the controls are styled, not just present.

Approach

Add a tiny client entry (import { initPage } from '@refrakt-md/html/client'; initPage();) and a bundling step to template-html (esbuild is lightest), emit to build/client.js, and pass scripts: ['/client.js'] to renderFullPage. Confirm the tree-shaken CSS includes the layout chrome stylesheets (or ship the theme barrel) so .rf-theme-toggle / .rf-search-trigger are styled.

References

  • SPEC-073
  • WORK-292 surfaced this gap (plain reference, not a dependency) — the no-flash injection landed there, but interactive cycling needs this bundle.

Resolution

Completed: 2026-06-11

Branch: claude/work-293-html-scaffold-client

What was done

  • template-html/client.ts (new): the client entry — import { initPage } from '@refrakt-md/html/client'; initPage();.
  • template-html/build.ts: an esbuild step bundles the entry → build/client.js (IIFE, minified, browser target — resolves @refrakt-md/html/client + @refrakt-md/behaviors into one classic script); renderFullPage is given scripts: ['/client.js']; and the layout-chrome stylesheets (default / theme-toggle / search / mobile / on-this-page) ship alongside the tree-shaken per-rune blocks (they aren't per-rune blocks, so the usage tree-shaking never included them — leaving the controls unstyled).
  • src/scaffold.ts: the generated template-html package.json gains esbuild (devDep) and @refrakt-md/behaviors (dep).

Verification (end-to-end, in-repo)

  • Ran build.ts against the template's own content: 2 pages + build/client.js (83 KB, bundled, valid classic script — no top-level import/export), all five chrome stylesheets emitted under build/styles/layouts/, and every page links /client.js + /styles/layouts/theme-toggle.css. renderFullPage emits #rf-context, so initPage gets its page context.

Why review, not done

  • Criterion 3 (working interactive runes verified in a browser — theme-toggle cycles + one other) needs the scaffold smoke test (create-refrakt a site, npm install, build, serve) against the 0.20.2 packages — not reproducible headlessly here. The bundle is present, valid, and carries the behaviours, and the theme-toggle CSS ships, so it should work; flip to done after the browser pass.

Discovered (out of scope)

  • The shipped template-html content has a nav-slug bug: _layout.md references getting-started but the page is at /docs/getting-started, so a fresh scaffold logs 2 build errors. Separate from this item — worth a quick follow-up fix.