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
+
+