diff --git a/.changeset/hip-months-invent.md b/.changeset/hip-months-invent.md new file mode 100644 index 0000000000..ea3484d71c --- /dev/null +++ b/.changeset/hip-months-invent.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix for putting the into its own component diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts index 99f7bf27b7..8d612d8482 100644 --- a/packages/astro/src/runtime/server/index.ts +++ b/packages/astro/src/runtime/server/index.ts @@ -707,7 +707,6 @@ export async function renderPage( children: any, streaming: boolean ): Promise { - let iterable: AsyncIterable; if (!componentFactory.isAstroComponentFactory) { const pageProps: Record = { ...(props ?? {}), 'server:root': true }; const output = await renderComponent( @@ -719,12 +718,17 @@ export async function renderPage( ); let html = output.toString(); if (!/\n${await maybeRenderHead(result)}${html}`; + let rest = html; + html = ``; + for await(let chunk of maybeRenderHead(result)) { + html += chunk; + } + html += rest; } return new Response(html, { headers: new Headers([ ['Content-Type', 'text/html; charset=utf-8'], - ['Content-Length', `${Buffer.byteLength(html, 'utf-8')}`], + ['Content-Length', Buffer.byteLength(html, 'utf-8').toString()], ]), }); } @@ -769,7 +773,7 @@ export async function renderPage( i++; } const bytes = encoder.encode(body); - headers.set('Content-Length', `${bytes.byteLength}`); + headers.set('Content-Length', bytes.byteLength.toString()); } let response = createResponse(body, { ...init, headers }); @@ -789,7 +793,7 @@ const uniqueElements = (item: any, index: number, all: any[]) => { }; const alreadyHeadRenderedResults = new WeakSet(); -export async function renderHead(result: SSRResult): Promise { +export function renderHead(result: SSRResult): Promise { alreadyHeadRenderedResults.add(result); const styles = Array.from(result.styles) .filter(uniqueElements) @@ -811,11 +815,11 @@ export async function renderHead(result: SSRResult): Promise { // This accomodates the fact that using a is optional in Astro, so this // is called before a component's first non-head HTML element. If the head was // already injected it is a noop. -export function maybeRenderHead(result: SSRResult): string | Promise { +export async function* maybeRenderHead(result: SSRResult): AsyncIterable { if (alreadyHeadRenderedResults.has(result)) { - return ''; + return; } - return renderHead(result); + yield renderHead(result); } export async function* renderAstroComponent( diff --git a/packages/astro/test/astro-head.test.js b/packages/astro/test/astro-head.test.js new file mode 100644 index 0000000000..862894d735 --- /dev/null +++ b/packages/astro/test/astro-head.test.js @@ -0,0 +1,23 @@ +import { expect } from 'chai'; +import * as cheerio from 'cheerio'; +import { loadFixture } from './test-utils.js'; + +describe('Head in its own component', () => { + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/astro-head/', + site: 'https://mysite.dev/', + base: '/blog', + }); + await fixture.build(); + }); + + it('Styles are appended to the head and not the body', async () => { + let html = await fixture.readFile('/head-own-component/index.html'); + let $ = cheerio.load(html); + expect($('link[rel=stylesheet]')).to.have.a.lengthOf(1, 'one stylesheet overall'); + expect($('head link[rel=stylesheet]')).to.have.a.lengthOf(1, 'stylesheet is in the head'); + }); +}); diff --git a/packages/astro/test/fixtures/astro-head/src/components/Head.astro b/packages/astro/test/fixtures/astro-head/src/components/Head.astro new file mode 100644 index 0000000000..cc289f7b4d --- /dev/null +++ b/packages/astro/test/fixtures/astro-head/src/components/Head.astro @@ -0,0 +1,11 @@ +--- +// Head.astro +const { title } = Astro.props; +--- + + + + + + {title} + diff --git a/packages/astro/test/fixtures/astro-head/src/pages/head-own-component.astro b/packages/astro/test/fixtures/astro-head/src/pages/head-own-component.astro new file mode 100644 index 0000000000..cbc99cb041 --- /dev/null +++ b/packages/astro/test/fixtures/astro-head/src/pages/head-own-component.astro @@ -0,0 +1,16 @@ +--- +// Layout.astro +import Head from "../components/Head.astro"; +--- + + + + + +

Title Here

+ +