diff options
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 /> |