Skip to content

Commit

Permalink
Fix head injection in body with slots.render() and head buffering (#6216
Browse files Browse the repository at this point in the history
)

* Fix head injection in body with slots.render() and head buffering

* Adding a changeset

* An MDX test too
  • Loading branch information
matthewp authored Feb 13, 2023
1 parent 79f49ac commit 79783fc
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/eight-cameras-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fix head injection in body with slots.render() and head buffering
11 changes: 10 additions & 1 deletion packages/astro/src/runtime/server/render/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
import SlotRenderComponent from "./SlotRenderComponent.astro";
---

<SlotRenderComponent>
<p slot="slot-name">Paragraph.</p>
</SlotRenderComponent>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
import Layout from "../components/Layout.astro";
import UsesSlotRender from "../components/UsesSlotRender.astro"
---
<Layout>
<UsesSlotRender />
</Layout>
8 changes: 8 additions & 0 deletions packages/astro/test/head-injection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
});
});
12 changes: 12 additions & 0 deletions packages/integrations/mdx/test/css-head-mdx.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
});
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<span>just a generic component</span>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
import Component from "./GenericComponent.astro";
---

<div>
<slot name="title" />
<slot name="intro" class="inline" />
<Component />
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
title: testing
---
import MDXWrapper from "../../components/MDXWrapper.astro";

<MDXWrapper>
<h1 slot="title">
testing
</h1>
<div slot="intro">
Intro
</div>
</MDXWrapper>
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
import BaseHead from "../components/BaseHead.astro";
export interface Props {
title: string;
}
Expand All @@ -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 />
Expand Down

0 comments on commit 79783fc

Please sign in to comment.