Skip to content

Commit e50f646

Browse files
authored
Fix head propagation for MDX components (#7838)
1 parent 365701f commit e50f646

File tree

10 files changed

+15
-52
lines changed

10 files changed

+15
-52
lines changed

.changeset/friendly-bulldogs-flash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Fix head propagation for MDX components

packages/astro/src/@types/astro.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2033,8 +2033,6 @@ export interface SSRMetadata {
20332033
headInTree: boolean;
20342034
extraHead: string[];
20352035
propagators: Map<AstroComponentFactory, AstroComponentInstance>;
2036-
// Used to key track of unique content; links and script tags
2037-
contentKeys: Set<string>;
20382036
}
20392037

20402038
/* Preview server stuff */

packages/astro/src/content/runtime.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
createHeadAndContent,
88
renderComponent,
99
renderTemplate,
10-
renderUniqueScriptElement,
10+
renderScriptElement,
1111
renderUniqueStylesheet,
1212
unescapeHTML,
1313
type AstroComponentFactory,
@@ -303,9 +303,7 @@ async function render({
303303
.join('');
304304
}
305305
if (Array.isArray(collectedScripts)) {
306-
scripts = collectedScripts
307-
.map((script: any) => renderUniqueScriptElement(result, script))
308-
.join('');
306+
scripts = collectedScripts.map((script: any) => renderScriptElement(script)).join('');
309307
}
310308

311309
let props = baseProps;

packages/astro/src/core/render/result.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ export function createResult(args: CreateResultArgs): SSRResult {
258258
headInTree: false,
259259
extraHead: [],
260260
propagators: new Map(),
261-
contentKeys: new Set(),
262261
},
263262
};
264263

packages/astro/src/runtime/server/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export {
2727
renderSlotToString,
2828
renderTemplate,
2929
renderToString,
30-
renderUniqueScriptElement,
3130
renderUniqueStylesheet,
3231
voidElementNames,
3332
} from './render/index.js';

packages/astro/src/runtime/server/render/astro/instance.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export class AstroComponentInstance {
3737
}
3838

3939
async init(result: SSRResult) {
40+
if (this.returnValue !== undefined) return this.returnValue;
4041
this.returnValue = this.factory(result, this.props, this.slotValues);
4142
return this.returnValue;
4243
}
@@ -72,7 +73,7 @@ function validateComponentProps(props: any, displayName: string) {
7273
}
7374
}
7475

75-
export async function createAstroComponentInstance(
76+
export function createAstroComponentInstance(
7677
result: SSRResult,
7778
displayName: string,
7879
factory: AstroComponentFactory,
@@ -81,16 +82,9 @@ export async function createAstroComponentInstance(
8182
) {
8283
validateComponentProps(props, displayName);
8384
const instance = new AstroComponentInstance(result, props, slots, factory);
84-
8585
if (isAPropagatingComponent(result, factory) && !result._metadata.propagators.has(factory)) {
8686
result._metadata.propagators.set(factory, instance);
87-
// Call component instances that might have head content to be propagated up.
88-
const returnValue = await instance.init(result);
89-
if (isHeadAndContent(returnValue)) {
90-
result._metadata.extraHead.push(returnValue.head);
91-
}
9287
}
93-
9488
return instance;
9589
}
9690

packages/astro/src/runtime/server/render/astro/render.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ export async function renderToReadableStream(
7171
// If the Astro component returns a Response on init, return that response
7272
if (templateResult instanceof Response) return templateResult;
7373

74+
let renderedFirstPageChunk = false;
75+
7476
if (isPage) {
7577
await bufferHeadContent(result);
7678
}
7779

78-
let renderedFirstPageChunk = false;
79-
8080
return new ReadableStream({
8181
start(controller) {
8282
const destination: RenderDestination = {
@@ -158,6 +158,7 @@ async function bufferHeadContent(result: SSRResult) {
158158
if (done) {
159159
break;
160160
}
161+
// Call component instances that might have head content to be propagated up.
161162
const returnValue = await value.init(result);
162163
if (isHeadAndContent(returnValue)) {
163164
result._metadata.extraHead.push(returnValue.head);

packages/astro/src/runtime/server/render/component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ async function renderAstroComponent(
420420
props: Record<string | number, any>,
421421
slots: any = {}
422422
): Promise<RenderInstance> {
423-
const instance = await createAstroComponentInstance(result, displayName, Component, props, slots);
423+
const instance = createAstroComponentInstance(result, displayName, Component, props, slots);
424424

425425
// Eagerly render the component so they are rendered in parallel
426426
const chunks: RenderDestinationChunk[] = [];

packages/astro/src/runtime/server/render/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ export { renderHTMLElement } from './dom.js';
66
export { maybeRenderHead, renderHead } from './head.js';
77
export { renderPage } from './page.js';
88
export { renderSlot, renderSlotToString, type ComponentSlots } from './slot.js';
9-
export { renderScriptElement, renderUniqueScriptElement, renderUniqueStylesheet } from './tags.js';
9+
export { renderScriptElement, renderUniqueStylesheet } from './tags.js';
1010
export type { RenderInstruction } from './types';
1111
export { addAttribute, defineScriptVars, voidElementNames } from './util.js';

packages/astro/src/runtime/server/render/tags.ts

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,45 +9,14 @@ export function renderScriptElement({ props, children }: SSRElement) {
99
});
1010
}
1111

12-
export function renderUniqueScriptElement(result: SSRResult, { props, children }: SSRElement) {
13-
if (
14-
Array.from(result.scripts).some((s) => {
15-
if (s.props.type === props.type && s.props.src === props.src) {
16-
return true;
17-
}
18-
if (!props.src && s.children === children) return true;
19-
})
20-
)
21-
return '';
22-
const key = `script-${props.type}-${props.src}-${children}`;
23-
if (checkOrAddContentKey(result, key)) return '';
24-
return renderScriptElement({ props, children });
25-
}
26-
2712
export function renderUniqueStylesheet(result: SSRResult, sheet: StylesheetAsset) {
2813
if (sheet.type === 'external') {
2914
if (Array.from(result.styles).some((s) => s.props.href === sheet.src)) return '';
30-
const key = 'link-external-' + sheet.src;
31-
if (checkOrAddContentKey(result, key)) return '';
32-
return renderElement('link', {
33-
props: {
34-
rel: 'stylesheet',
35-
href: sheet.src,
36-
},
37-
children: '',
38-
});
15+
return renderElement('link', { props: { rel: 'stylesheet', href: sheet.src }, children: '' });
3916
}
4017

4118
if (sheet.type === 'inline') {
4219
if (Array.from(result.styles).some((s) => s.children.includes(sheet.content))) return '';
43-
const key = `link-inline-` + sheet.content;
44-
if (checkOrAddContentKey(result, key)) return '';
4520
return renderElement('style', { props: { type: 'text/css' }, children: sheet.content });
4621
}
4722
}
48-
49-
function checkOrAddContentKey(result: SSRResult, key: string): boolean {
50-
if (result._metadata.contentKeys.has(key)) return true;
51-
result._metadata.contentKeys.add(key);
52-
return false;
53-
}

0 commit comments

Comments
 (0)