Skip to content

Commit e92c39c

Browse files
committed
fix: extract meta from custom index.html properly, close #2152
1 parent 018aa1d commit e92c39c

File tree

2 files changed

+13
-13
lines changed

2 files changed

+13
-13
lines changed

packages/client/index.html

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<!-- head -->
76
</head>
87
<body>
98
<div id="app"></div>

packages/slidev/node/setups/indexHtml.ts

+13-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { join } from 'node:path'
55
import { slash } from '@antfu/utils'
66
import { white, yellow } from 'ansis'
77
import { escapeHtml } from 'markdown-it/lib/common/utils.mjs'
8-
import { createHead, transformHtmlTemplate } from 'unhead/server'
8+
import { createHead, extractUnheadInputFromHtml, transformHtmlTemplate } from 'unhead/server'
99
import { version } from '../../package.json'
1010
import { getSlideTitle } from '../commands/shared'
1111
import { toAtFS } from '../resolver'
@@ -17,24 +17,25 @@ function toAttrValue(unsafe: unknown) {
1717

1818
export default async function setupIndexHtml({ mode, entry, clientRoot, userRoot, roots, data, base }: Omit<ResolvedSlidevOptions, 'utils'>): Promise<string> {
1919
let main = readFileSync(join(clientRoot, 'index.html'), 'utf-8')
20-
let head = ''
2120
let body = ''
2221

22+
const inputs: any[] = []
23+
2324
for (const root of roots) {
2425
const path = join(root, 'index.html')
2526
if (!existsSync(path))
2627
continue
2728

28-
const index = readFileSync(path, 'utf-8')
29+
const html = readFileSync(path, 'utf-8')
2930

30-
if (root === userRoot && index.includes('<!DOCTYPE')) {
31+
if (root === userRoot && html.includes('<!DOCTYPE')) {
3132
console.error(yellow(`[Slidev] Ignored provided index.html with doctype declaration. (${white(path)})`))
3233
console.error(yellow('This file may be generated by Slidev, please remove it from your project.'))
3334
continue
3435
}
3536

36-
head += `\n${(index.match(/<head>([\s\S]*?)<\/head>/i)?.[1] || '').trim()}`
37-
body += `\n${(index.match(/<body>([\s\S]*?)<\/body>/i)?.[1] || '').trim()}`
37+
inputs.push(extractUnheadInputFromHtml(html).input)
38+
body += `\n${(html.match(/<body>([\s\S]*?)<\/body>/i)?.[1] || '').trim()}`
3839
}
3940

4041
if (data.features.tweet) {
@@ -60,12 +61,12 @@ export default async function setupIndexHtml({ mode, entry, clientRoot, userRoot
6061
const unhead = createHead({
6162
init: [
6263
{
63-
htmlAttrs: { lang: (data.headmatter.lang as string | undefined) ?? 'en' },
64+
htmlAttrs: data.headmatter.lang ? { lang: data.headmatter.lang as string } : undefined,
6465
title,
6566
link: [
66-
{ rel: 'icon', href: data.config.favicon },
67+
data.config.favicon ? { rel: 'icon', href: data.config.favicon } : null,
6768
...webFontsLink,
68-
],
69+
].filter(x => x),
6970
meta: [
7071
{ property: 'slidev:version', content: version },
7172
{ charset: 'slidev:entry', content: mode === 'dev' && slash(entry) },
@@ -82,18 +83,18 @@ export default async function setupIndexHtml({ mode, entry, clientRoot, userRoot
8283
{ property: 'twitter:description', content: seoMeta.twitterDescription },
8384
{ property: 'twitter:image', content: seoMeta.twitterImage },
8485
{ property: 'twitter:url', content: seoMeta.twitterUrl },
85-
],
86+
].filter(x => x.content),
8687
},
88+
...inputs,
8789
],
8890
})
8991

9092
const baseInDev = mode === 'dev' && base ? base.slice(0, -1) : ''
93+
9194
main = main
9295
.replace('__ENTRY__', baseInDev + toAtFS(join(clientRoot, 'main.ts')))
93-
.replace('<!-- head -->', head)
9496
.replace('<!-- body -->', body)
9597

9698
const html = await transformHtmlTemplate(unhead, main)
97-
9899
return html
99100
}

0 commit comments

Comments
 (0)