Skip to content

Commit fadcf29

Browse files
committed
feat: head.startElements support
1 parent 34efcd2 commit fadcf29

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

src/plugins/prerender-plugin.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
383383
};
384384

385385
/** @type {import('./types.d.ts').Head} */
386-
let head = { lang: '', title: '', elements: new Set() };
386+
let head = { lang: '', title: '', elements: new Set(), startElements: new Set() };
387387

388388
let prerender;
389389
try {
@@ -435,7 +435,7 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
435435

436436
// Reset HTML doc & head data
437437
const htmlDoc = htmlParse(tpl, { comment: true });
438-
head = { lang: '', title: '', elements: new Set() };
438+
head = { lang: '', title: '', elements: new Set(), startElements: new Set() };
439439

440440
// Add any discovered links to the list of routes to pre-render:
441441
if (result.links) {
@@ -480,6 +480,16 @@ export function prerenderPlugin({ prerenderScript, renderTarget, additionalPrere
480480
htmlDoc.querySelector('html').setAttribute('lang', enc(head.lang));
481481
}
482482

483+
if (head.startElements) {
484+
// Inject HTML links at the start of <head> for any stylesheets injected during rendering of the page:
485+
htmlHead.insertAdjacentHTML(
486+
'afterbegin',
487+
Array.from(
488+
new Set(Array.from(head.startElements).map(serializeElement)),
489+
).join('\n'),
490+
);
491+
}
492+
483493
if (head.elements) {
484494
// Inject HTML links at the end of <head> for any stylesheets injected during rendering of the page:
485495
htmlHead.insertAdjacentHTML(

src/plugins/types.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ export interface HeadElement {
77
export interface Head {
88
lang: string;
99
title: string;
10+
/**
11+
* Which elements should be injected in the **start** of <head>
12+
*/
13+
startElements: Set<HeadElement>;
14+
/**
15+
* Which elements should be injected in the **end** of <head>
16+
*/
1017
elements: Set<HeadElement>;
1118
}
1219

tests/prerender-api.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,29 @@ test('Should support `head.title` property', async () => {
9494
assert.match(prerenderedHtml, '<title>My Prerendered Site</title>');
9595
});
9696

97+
test('Should support `head.startElements` property', async () => {
98+
await loadFixture('simple', env);
99+
await writeEntry(
100+
env.tmp.path,
101+
`
102+
export async function prerender() {
103+
return {
104+
html: '<h1>Hello, World!</h1>',
105+
head: {
106+
startElements: new Set([
107+
{ type: 'link', props: { rel: 'stylesheet', href: 'foo.css' } },
108+
]),
109+
},
110+
};
111+
}
112+
`,
113+
);
114+
await viteBuild(env.tmp.path);
115+
116+
const prerenderedHtml = await getOutputFile(env.tmp.path, 'index.html');
117+
assert.match(prerenderedHtml, '<link rel="stylesheet" href="foo.css">');
118+
});
119+
97120
test('Should support `head.elements` property', async () => {
98121
await loadFixture('simple', env);
99122
await writeEntry(env.tmp.path, `

0 commit comments

Comments
 (0)