mirror of
https://github.com/withastro/astro.git
synced 2025-03-03 22:57:08 -05:00
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()
|
// 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)) {
|
if (hasScopeFlag(result, ScopeFlags.RenderSlot)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
break;
|
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.
|
// Astro.slots.render() should never render head content.
|
||||||
case ScopeFlags.RenderSlot | ScopeFlags.Astro:
|
case ScopeFlags.RenderSlot | ScopeFlags.Astro:
|
||||||
case ScopeFlags.RenderSlot | ScopeFlags.Astro | ScopeFlags.JSX:
|
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($('head link[rel=stylesheet]')).to.have.a.lengthOf(2);
|
||||||
expect($('body link[rel=stylesheet]')).to.have.a.lengthOf(0);
|
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]');
|
const bodyLinks = $('body link[rel=stylesheet]');
|
||||||
expect(bodyLinks).to.have.a.lengthOf(0);
|
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 {
|
export interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
@ -9,14 +10,7 @@ const { title } = Astro.props;
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<BaseHead title={title} />
|
||||||
<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>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<slot />
|
<slot />
|
||||||
|
|
Loading…
Add table
Reference in a new issue