Framework finding, isolated while auditing bench against stx-standards §4. Filed here because it explains a large piece of this repo's architecture and should not be "cleaned up" by a future reader.
The claim it tests
stx-standards §4.0.1 marks useSeoMeta(config) in a <script server> block as "MUST — the default", working for title, description, all og:* and all twitter:*, with useHead({ link }) for canonical. That table was verified against stx 0.2.113.
bench does none of that. It computes heads in app/Helpers/{seoPages,entitySeo}.ts and splices them into the built HTML afterwards. On the face of it that is reinvention.
It is not. @extends discards the server-scope head.
Three controlled probes through processDirectives on bench's own stx 0.2.176, each with an identical <script server> calling useSeoMeta({ title, description, ogTitle }) and useHead({ link: canonical }):
| view shape | title | description / og / canonical |
|---|---|---|
no @extends | Enrique S. Lamoutte — Judge Profile | all present |
@extends + @section('title', 'X') | X | all gone |
@extends, no @section | stx App | all gone |
The third row is the diagnostic one. stx App is tier 5 — generateDocumentShell's hardcoded default — so the chain fell past tier 1 (context.__stx_runtime_head) and tier 4 (config/ui.ts app.head.title). The head is being lost, not overridden.
And it is not a competing shell: resources/layouts/default.stx is ten lines of body content with no <!DOCTYPE>, <html> or <head> of its own.
Classification: stx, not bench. Correctly-authored input — the standards' own MUST — works with autoShell and is silently dropped under @extends, with no warning.
Why this matters here
Every bench view uses @extends. So:
- The build-time injection layer is a justified workaround for a framework gap, not reinvention. Do not delete it on the strength of §4.0.1.
- §4.0.1's table is accurate only for layout-less pages. Worth flagging upstream, since an agent following the standards literally will write
useSeoMetain a<script server>, see a plausible-looking title from@section, and ship pages with no description, no og and no canonical — silently. - Three SEO fixes landed this week (
6b2eb19,37f9884,83d0b6d) inside that layer. They were right to be there.
Repro
bun -e '
const { processDirectives, resetHead } = await import("@stacksjs/stx")
const ui = (await import("./config/ui.ts")).default
resetHead()
const out = await processDirectives(await Bun.file(F).text(), {}, F,
{ ...ui, autoShell: true, seo: { enabled: true } }, new Set())
console.log(out.match(/<title[^>]*>[^<]*<\/title>/i), /name="description"/.test(out))'against two files differing only by an @extends line.
Next
- File upstream against stx with the three-case repro
- Until fixed, keep
useSeoMeta/useHeadout of<script server>in this repo — it reads as working and is not