Fix head injection in body with slots.render() and head buffering (#6216)
* Fix head injection in body with slots.render() and head buffering * Adding a changeset * An MDX test too
This commit is contained in:
parent
79f49acbe1
commit
79783fc018
11 changed files with 85 additions and 9 deletions
5
.changeset/eight-cameras-itch.md
Normal file
5
.changeset/eight-cameras-itch.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fix head injection in body with slots.render() and head buffering
|
|
@ -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:
|
||||
|
|
7
packages/astro/test/fixtures/head-injection/src/components/UsesSlotRender.astro
vendored
Normal file
7
packages/astro/test/fixtures/head-injection/src/components/UsesSlotRender.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import SlotRenderComponent from "./SlotRenderComponent.astro";
|
||||
---
|
||||
|
||||
<SlotRenderComponent>
|
||||
<p slot="slot-name">Paragraph.</p>
|
||||
</SlotRenderComponent>
|
7
packages/astro/test/fixtures/head-injection/src/pages/with-render-slot-in-head-buffer.astro
vendored
Normal file
7
packages/astro/test/fixtures/head-injection/src/pages/with-render-slot-in-head-buffer.astro
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
import Layout from "../components/Layout.astro";
|
||||
import UsesSlotRender from "../components/UsesSlotRender.astro"
|
||||
---
|
||||
<Layout>
|
||||
<UsesSlotRender />
|
||||
</Layout>
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
11
packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/BaseHead.astro
vendored
Normal file
11
packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/BaseHead.astro
vendored
Normal file
|
@ -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>
|
1
packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/GenericComponent.astro
vendored
Normal file
1
packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/GenericComponent.astro
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<span>just a generic component</span>
|
9
packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/MDXWrapper.astro
vendored
Normal file
9
packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/MDXWrapper.astro
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
import Component from "./GenericComponent.astro";
|
||||
---
|
||||
|
||||
<div>
|
||||
<slot name="title" />
|
||||
<slot name="intro" class="inline" />
|
||||
<Component />
|
||||
</div>
|
13
packages/integrations/mdx/test/fixtures/css-head-mdx/src/content/posts/using-component.mdx
vendored
Normal file
13
packages/integrations/mdx/test/fixtures/css-head-mdx/src/content/posts/using-component.mdx
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
title: testing
|
||||
---
|
||||
import MDXWrapper from "../../components/MDXWrapper.astro";
|
||||
|
||||
<MDXWrapper>
|
||||
<h1 slot="title">
|
||||
testing
|
||||
</h1>
|
||||
<div slot="intro">
|
||||
Intro
|
||||
</div>
|
||||
</MDXWrapper>
|
|
@ -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 />
|
||||
|
|
Loading…
Reference in a new issue