Prevent body head content injection in MDX when using layout (#6779)

This commit is contained in:
Matthew Phillips 2023-04-06 18:33:47 -04:00 committed by GitHub
parent e0ee7765d0
commit a98f6f418c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 63 additions and 0 deletions

View file

@ -0,0 +1,6 @@
---
'astro': patch
'@astrojs/mdx': patch
---
Prevent body head content injection in MDX when using layout

View file

@ -76,6 +76,8 @@ export async function renderPage(
route?: RouteData | undefined
): Promise<Response> {
if (!isAstroComponentFactory(componentFactory)) {
result._metadata.headInTree =
result.componentMetadata.get((componentFactory as any).moduleId)?.containsHead ?? false;
const pageProps: Record<string, any> = { ...(props ?? {}), 'server:root': true };
let output: ComponentIterable;

View file

@ -160,6 +160,7 @@ export default function mdx(partialMdxOptions: Partial<MdxOptions> = {}): AstroI
// Ensures styles and scripts are injected into a `<head>`
// When a layout is not applied
code += `\nContent[Symbol.for('astro.needsHeadRendering')] = !Boolean(frontmatter.layout);`;
code += `\nContent.moduleId = ${JSON.stringify(id)};`
if (command === 'dev') {
// TODO: decline HMR updates until we have a stable approach

View file

@ -81,5 +81,18 @@ describe('Head injection w/ MDX', () => {
const bodyLinks = $('body link[rel=stylesheet]');
expect(bodyLinks).to.have.a.lengthOf(0);
});
it('Injection caused by delayed slots', async () => {
const html = await fixture.readFile('/componentwithtext/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);
});
});
});

View file

@ -0,0 +1,14 @@
---
const { inlineStyle, title, display = 'horizontal' } = Astro.props;
const lineEnding = display === 'horizontal' ? ', ' : '<br>';
---
{title && <h2 set:html={title} />}
<address style={inlineStyle}>
<span class="name">some name</span><Fragment set:html={lineEnding} />
line 1<Fragment set:html={lineEnding} />
line 2<Fragment set:html={lineEnding} />
line 3<Fragment set:html={lineEnding} />
line 4<Fragment set:html={lineEnding} />
line 5
</address>

View file

@ -0,0 +1,15 @@
---
// Extend the BaseLayout, adding space for a banner at the top of the page
// after the main heading, then the detail for the actual page
import ContentLayout from './ContentLayout.astro';
const { frontmatter } = Astro.props;
---
<ContentLayout>
<div class="content-container">
<article id="main-content" class="pad-z5 flow">
<h1 set:html={frontmatter.pageHeading ? frontmatter.pageHeading : frontmatter.title} />
<slot />
</article>
</div>
</ContentLayout>

View file

@ -0,0 +1,12 @@
---
layout: ../layouts/DocumentLayout.astro
title: blah blah
---
import BasicBlock from '../components/BasicBlock.astro';
Some text for a paragraph.
<BasicBlock title="This causes css in wrong place." />
Some other text.