Skip to content

Commit d450124

Browse files
committed
fix(unhead): safer removal of leading / trailing separators
Fixes #561
1 parent 1d205d5 commit d450124

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

packages/unhead/src/utils/templateParams.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { TemplateParams } from '../types'
22

33
const SepSub = '%separator'
4-
const SepSubRE = new RegExp(`${SepSub}(?:\\s*${SepSub})*`, 'g')
54

65
// for each %<word> token replace it with the corresponding runtime config or an empty value
76
function sub(p: TemplateParams, token: string, isJson = false) {
@@ -61,12 +60,10 @@ export function processTemplateParams(s: string, p: TemplateParams, sep?: string
6160
// we need to remove separators if they're next to each other or if they're at the start or end of the string
6261
// for example: %separator %separator %title should return %title
6362
if (hasSepSub) {
64-
if (s.endsWith(SepSub))
65-
s = s.slice(0, -SepSub.length)
66-
if (s.startsWith(SepSub))
67-
s = s.slice(SepSub.length)
68-
// make sure we don't have two separators next to each other
69-
s = s.replace(SepSubRE, sep || '').trim()
63+
s = s.split(SepSub)
64+
.map(part => part.trim())
65+
.filter(Boolean)
66+
.join(` ${sep || ''} `)
7067
}
7168
return s
7269
}

packages/unhead/test/unit/client/templateParams.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,30 @@ describe('templateParams', () => {
220220
</body></html>"
221221
`)
222222
})
223+
224+
it('edge case #561', async () => {
225+
const dom = useDom({
226+
headTags: '<title>Vite</title>',
227+
})
228+
const head = createClientHeadWithContext({
229+
document: dom.window.document,
230+
plugins: [TemplateParamsPlugin],
231+
})
232+
// The test should ensure that:
233+
// 1. The existing title "Vite" is captured as %s
234+
// 2. Empty string companyName stays empty (not converted to true)
235+
// 3. The separator adjacent to empty values should be removed
236+
useHead(head, {
237+
titleTemplate: `%s %separator %companyName %separator %siteTitle`,
238+
templateParams: {
239+
companyName: '',
240+
siteTitle: 'Site title',
241+
},
242+
})
243+
const html = await new Promise<string>((resolve) => {
244+
setTimeout(() => resolve(dom!.serialize()), 250)
245+
})
246+
247+
expect(html).toContain('<title>Site title</title>')
248+
})
223249
})

0 commit comments

Comments
 (0)