summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/eight-cameras-itch.md5
-rw-r--r--packages/astro/src/runtime/server/render/common.ts11
-rw-r--r--packages/astro/test/fixtures/head-injection/src/components/UsesSlotRender.astro7
-rw-r--r--packages/astro/test/fixtures/head-injection/src/pages/with-render-slot-in-head-buffer.astro7
-rw-r--r--packages/astro/test/head-injection.test.js8
-rw-r--r--packages/integrations/mdx/test/css-head-mdx.test.js12
-rw-r--r--packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/BaseHead.astro11
-rw-r--r--packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/GenericComponent.astro1
-rw-r--r--packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/MDXWrapper.astro9
-rw-r--r--packages/integrations/mdx/test/fixtures/css-head-mdx/src/content/posts/using-component.mdx13
-rw-r--r--packages/integrations/mdx/test/fixtures/css-head-mdx/src/layouts/ContentLayout.astro10
11 files changed, 85 insertions, 9 deletions
diff --git a/.changeset/eight-cameras-itch.md b/.changeset/eight-cameras-itch.md
new file mode 100644
index 000000000..4499c5a46
--- /dev/null
+++ b/.changeset/eight-cameras-itch.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fix head injection in body with slots.render() and head buffering
diff --git a/packages/astro/src/runtime/server/render/common.ts b/packages/astro/src/runtime/server/render/common.ts
index 6bcd72cc5..a33ed435d 100644
--- a/packages/astro/src/runtime/server/render/common.ts
+++ b/packages/astro/src/runtime/server/render/common.ts
@@ -72,13 +72,22 @@ export function stringifyChunk(result: SSRResult, chunk: string | SlotString | R
}
// If the current scope is with Astro.slots.render()
- case ScopeFlags.Slot: {
+ case ScopeFlags.Slot:
+ case ScopeFlags.Slot | ScopeFlags.HeadBuffer: {
if (hasScopeFlag(result, ScopeFlags.RenderSlot)) {
return '';
}
break;
}
+ // Nested element inside of JSX during head buffering phase
+ case ScopeFlags.HeadBuffer: {
+ if(hasScopeFlag(result, ScopeFlags.JSX | ScopeFlags.HeadBuffer)) {
+ return "";
+ }
+ break;
+ }
+
// Astro.slots.render() should never render head content.
case ScopeFlags.RenderSlot | ScopeFlags.Astro:
case ScopeFlags.RenderSlot | ScopeFlags.Astro | ScopeFlags.JSX:
diff --git a/packages/astro/test/fixtures/head-injection/src/components/UsesSlotRender.astro b/packages/astro/test/fixtures/head-injection/src/components/UsesSlotRender.astro
new file mode 100644
index 000000000..35d127cd5
--- /dev/null
+++ b/packages/astro/test/fixtures/head-injection/src/components/UsesSlotRender.astro
@@ -0,0 +1,7 @@
+---
+import SlotRenderComponent from "./SlotRenderComponent.astro";
+---
+
+<SlotRenderComponent>
+ <p slot="slot-name">Paragraph.</p>
+</SlotRenderComponent>
diff --git a/packages/astro/test/fixtures/head-injection/src/pages/with-render-slot-in-head-buffer.astro b/packages/astro/test/fixtures/head-injection/src/pages/with-render-slot-in-head-buffer.astro
new file mode 100644
index 000000000..5cd5c6261
--- /dev/null
+++ b/packages/astro/test/fixtures/head-injection/src/pages/with-render-slot-in-head-buffer.astro
@@ -0,0 +1,7 @@
+---
+import Layout from "../components/Layout.astro";
+import UsesSlotRender from "../components/UsesSlotRender.astro"
+---
+<Layout>
+ <UsesSlotRender />
+</Layout>
diff --git a/packages/astro/test/head-injection.test.js b/packages/astro/test/head-injection.test.js
index d06a6eed0..d86272712 100644
--- a/packages/astro/test/head-injection.test.js
+++ b/packages/astro/test/head-injection.test.js
@@ -50,6 +50,14 @@ describe('Head injection', () => {
expect($('head link[rel=stylesheet]')).to.have.a.lengthOf(2);
expect($('body link[rel=stylesheet]')).to.have.a.lengthOf(0);
});
+
+ it('Using slots in Astro.slots.render() inside head buffering', async () => {
+ const html = await fixture.readFile('/with-render-slot-in-head-buffer/index.html');
+ const $ = cheerio.load(html);
+
+ expect($('head link[rel=stylesheet]')).to.have.a.lengthOf(2);
+ expect($('body link[rel=stylesheet]')).to.have.a.lengthOf(0);
+ });
});
});
});
diff --git a/packages/integrations/mdx/test/css-head-mdx.test.js b/packages/integrations/mdx/test/css-head-mdx.test.js
index bb2c7c0ef..781e4d62d 100644
--- a/packages/integrations/mdx/test/css-head-mdx.test.js
+++ b/packages/integrations/mdx/test/css-head-mdx.test.js
@@ -69,5 +69,17 @@ describe('Head injection w/ MDX', () => {
const bodyLinks = $('body link[rel=stylesheet]');
expect(bodyLinks).to.have.a.lengthOf(0);
});
+
+ it('JSX component rendering Astro children within head buffering phase', async () => {
+ const html = await fixture.readFile('/posts/using-component/index.html');
+ // Using cheerio here because linkedom doesn't support head tag injection
+ const $ = cheerio.load(html);
+
+ const headLinks = $('head link[rel=stylesheet]');
+ expect(headLinks).to.have.a.lengthOf(1);
+
+ const bodyLinks = $('body link[rel=stylesheet]');
+ expect(bodyLinks).to.have.a.lengthOf(0);
+ });
});
});
diff --git a/packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/BaseHead.astro b/packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/BaseHead.astro
new file mode 100644
index 000000000..19f517789
--- /dev/null
+++ b/packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/BaseHead.astro
@@ -0,0 +1,11 @@
+---
+const { title } = Astro.props;
+---
+<meta charset="UTF-8" />
+<meta name="viewport" content="width=device-width" />
+<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+<meta name="generator" content={Astro.generator} />
+<title>{title}</title>
+<style is:global>
+ @import "../styles/global.css";
+</style>
diff --git a/packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/GenericComponent.astro b/packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/GenericComponent.astro
new file mode 100644
index 000000000..ebcd3ff35
--- /dev/null
+++ b/packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/GenericComponent.astro
@@ -0,0 +1 @@
+<span>just a generic component</span>
diff --git a/packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/MDXWrapper.astro b/packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/MDXWrapper.astro
new file mode 100644
index 000000000..fbd530e14
--- /dev/null
+++ b/packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/MDXWrapper.astro
@@ -0,0 +1,9 @@
+---
+import Component from "./GenericComponent.astro";
+---
+
+<div>
+ <slot name="title" />
+ <slot name="intro" class="inline" />
+ <Component />
+</div>
diff --git a/packages/integrations/mdx/test/fixtures/css-head-mdx/src/content/posts/using-component.mdx b/packages/integrations/mdx/test/fixtures/css-head-mdx/src/content/posts/using-component.mdx
new file mode 100644
index 000000000..fa550fb04
--- /dev/null
+++ b/packages/integrations/mdx/test/fixtures/css-head-mdx/src/content/posts/using-component.mdx
@@ -0,0 +1,13 @@
+---
+title: testing
+---
+import MDXWrapper from "../../components/MDXWrapper.astro";
+
+<MDXWrapper>
+ <h1 slot="title">
+ testing
+ </h1>
+ <div slot="intro">
+ Intro
+ </div>
+</MDXWrapper>
diff --git a/packages/integrations/mdx/test/fixtures/css-head-mdx/src/layouts/ContentLayout.astro b/packages/integrations/mdx/test/fixtures/css-head-mdx/src/layouts/ContentLayout.astro
index 7b234e868..e67060136 100644
--- a/packages/integrations/mdx/test/fixtures/css-head-mdx/src/layouts/ContentLayout.astro
+++ b/packages/integrations/mdx/test/fixtures/css-head-mdx/src/layouts/ContentLayout.astro
@@ -1,4 +1,5 @@
---
+import BaseHead from "../components/BaseHead.astro";
export interface Props {
title: string;
}
@@ -9,14 +10,7 @@ const { title } = Astro.props;
<!DOCTYPE html>
<html lang="en">
<head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width" />
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
- <meta name="generator" content={Astro.generator} />
- <title>{title}</title>
- <style is:global>
- @import "../styles/global.css";
- </style>
+ <BaseHead title={title} />
</head>
<body>
<slot />