Repository navigation
Fixes two faults in how a C# page is composed with the page Astro builds around it. Both affected
pages that ship to production, so upgrading is recommended.
npm install astrosharp@0.0.3A page that renders its own document lost its head content
A .razor page with no [AstroLayout] renders the whole document itself, and was handed to Astro as
opaque markup with nowhere to put the page's head content. Everything arriving through the head was
dropped silently:
- the page's own scoped
<style>blocks — the built HTML had no stylesheet and no CSS asset was
emitted at all, leaving an element carrying a scope attribute whose rule existed nowhere - Astro's dev client — so the page could not hot-reload
The second explains why the first looked intermittent: with no dev client, a page never learned it
had been fixed, so a change that worked appeared to need a server restart. It did not — the page had
no way to be told.
Such a page now renders Astro's head into the gap where its own document closes </head>, which is
what the .astro compiler emits for exactly this shape. A [AstroPage(Partial = true)] page is
unaffected: a fragment gets no head content, in Astro or here.
Response status and headers now match Astro
A page declaring a layout rendered its C# inside the layout's <slot />, which is after Astro
snapshots the response headers. A header set from C# was applied and then discarded, and the status
went with it — a page asking for 418 answered 200.
The previous behaviour was asserted in the tests and justified as Astro's own rule. It is not: an
.astro page keeps its status and headers whether or not it uses a layout, because frontmatter runs
before the template. A .razor page's @code block is frontmatter, so it now runs in the same
place.
| before | after | Astro | |
|---|---|---|---|
| own document — header | dropped | kept | kept |
| own document — status | kept | kept | kept |
| with a layout — header | dropped | kept | kept |
| with a layout — status | lost (200) | kept (418) | kept |
A header set by a .razor component is still lost, exactly as it is for an .astro component.
That one really is Astro's rule.
The trade-off, measured
Rendering before the layout means the layout's <head> can no longer be flushed while the page
renders. On a page whose C# takes 1.5 seconds, first byte moves from 3ms to 1505ms.
This is the same thing Astro does when the slow work is in frontmatter — measured at 1511ms — and a
.razor page's @code block is frontmatter. The page body never streamed in either version: it is
one round trip to the .NET host. What is lost is only the early head flush, and only for pages doing
slow work in C#.
Gating eager rendering on whether a page touches Astro.Response would recover the flush for pages
that do not. It is not in this release.
Testing
The new assertions were checked against the fault rather than assumed: reverting the change turns
exactly those tests red and nothing else. They include the ordering of the two calls in the generated
module, because that ordering is the behaviour and it is invisible in the rendered HTML.