Skip to content

Commit e23dbac

Browse files
committed
fix(ssr): broken extractUnheadInputFromHtml regex
Fixes #578
1 parent f352fce commit e23dbac

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

packages/unhead/src/server/util/extractUnheadInputFromHtml.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { SerializableHead } from '../../types'
22

3-
const Attrs = /(\w+-?\w+)(?:=["']([^"']*)["'])?/g
3+
const Attrs = /([\w-]+)(?:=["']([^"']*)["'])?/g
44
const HtmlTag = /<html[^>]*>/
55
const BodyTag = /<body[^>]*>/
66
const HeadContent = /<head[^>]*>(.*?)<\/head>/s
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { extractUnheadInputFromHtml } from '../../../src/server/util/extractUnheadInputFromHtml'
3+
4+
describe('extractUnheadInputFromHtml', () => {
5+
it('should handle data-vue-ssr-id attribute correctly', () => {
6+
const html = `
7+
<html>
8+
<head>
9+
<style data-vue-ssr-id="12345678">
10+
.test { color: red; }
11+
</style>
12+
</head>
13+
<body>
14+
</body>
15+
</html>
16+
`
17+
18+
const result = extractUnheadInputFromHtml(html)
19+
20+
// The bug causes data-vue-ssr-id to be split into data-vue="true" and ssr-id="12345678"
21+
// This test should fail with the current implementation
22+
expect(result.input.style).toBeDefined()
23+
expect(result.input.style?.[0]).toEqual({
24+
'data-vue-ssr-id': '12345678',
25+
'textContent': '\n .test { color: red; }\n ',
26+
})
27+
})
28+
29+
it('should handle multiple hyphenated attributes', () => {
30+
const html = `
31+
<html>
32+
<head>
33+
<meta data-custom-attr="value1" another-hyphenated-attr="value2" />
34+
</head>
35+
<body>
36+
</body>
37+
</html>
38+
`
39+
40+
const result = extractUnheadInputFromHtml(html)
41+
42+
expect(result.input.meta).toBeDefined()
43+
expect(result.input.meta?.[0]).toEqual({
44+
'data-custom-attr': 'value1',
45+
'another-hyphenated-attr': 'value2',
46+
})
47+
})
48+
49+
it('should handle attributes with multiple hyphens', () => {
50+
const html = `
51+
<html>
52+
<head>
53+
<link data-vue-ssr-id="abc123" rel="stylesheet" href="/style.css" />
54+
</head>
55+
<body>
56+
</body>
57+
</html>
58+
`
59+
60+
const result = extractUnheadInputFromHtml(html)
61+
62+
expect(result.input.link).toBeDefined()
63+
expect(result.input.link?.[0]).toEqual({
64+
'data-vue-ssr-id': 'abc123',
65+
'rel': 'stylesheet',
66+
'href': '/style.css',
67+
})
68+
})
69+
})

0 commit comments

Comments
 (0)