Prevent body head content injection in MDX when using layout (#6779)
This commit is contained in:
parent
e0ee7765d0
commit
a98f6f418c
7 changed files with 63 additions and 0 deletions
6
.changeset/smart-files-flow.md
Normal file
6
.changeset/smart-files-flow.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
'@astrojs/mdx': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Prevent body head content injection in MDX when using layout
|
|
@ -76,6 +76,8 @@ export async function renderPage(
|
||||||
route?: RouteData | undefined
|
route?: RouteData | undefined
|
||||||
): Promise<Response> {
|
): Promise<Response> {
|
||||||
if (!isAstroComponentFactory(componentFactory)) {
|
if (!isAstroComponentFactory(componentFactory)) {
|
||||||
|
result._metadata.headInTree =
|
||||||
|
result.componentMetadata.get((componentFactory as any).moduleId)?.containsHead ?? false;
|
||||||
const pageProps: Record<string, any> = { ...(props ?? {}), 'server:root': true };
|
const pageProps: Record<string, any> = { ...(props ?? {}), 'server:root': true };
|
||||||
|
|
||||||
let output: ComponentIterable;
|
let output: ComponentIterable;
|
||||||
|
|
|
@ -160,6 +160,7 @@ export default function mdx(partialMdxOptions: Partial<MdxOptions> = {}): AstroI
|
||||||
// Ensures styles and scripts are injected into a `<head>`
|
// Ensures styles and scripts are injected into a `<head>`
|
||||||
// When a layout is not applied
|
// When a layout is not applied
|
||||||
code += `\nContent[Symbol.for('astro.needsHeadRendering')] = !Boolean(frontmatter.layout);`;
|
code += `\nContent[Symbol.for('astro.needsHeadRendering')] = !Boolean(frontmatter.layout);`;
|
||||||
|
code += `\nContent.moduleId = ${JSON.stringify(id)};`
|
||||||
|
|
||||||
if (command === 'dev') {
|
if (command === 'dev') {
|
||||||
// TODO: decline HMR updates until we have a stable approach
|
// TODO: decline HMR updates until we have a stable approach
|
||||||
|
|
|
@ -81,5 +81,18 @@ 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('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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
14
packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/BasicBlock.astro
vendored
Normal file
14
packages/integrations/mdx/test/fixtures/css-head-mdx/src/components/BasicBlock.astro
vendored
Normal 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>
|
15
packages/integrations/mdx/test/fixtures/css-head-mdx/src/layouts/DocumentLayout.astro
vendored
Normal file
15
packages/integrations/mdx/test/fixtures/css-head-mdx/src/layouts/DocumentLayout.astro
vendored
Normal 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>
|
12
packages/integrations/mdx/test/fixtures/css-head-mdx/src/pages/componentwithtext.mdx
vendored
Normal file
12
packages/integrations/mdx/test/fixtures/css-head-mdx/src/pages/componentwithtext.mdx
vendored
Normal 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.
|
Loading…
Reference in a new issue