Skip to content

Commit f52f20e

Browse files
committed
fix: avoid resetting head tags on hmr/page switch
1 parent 834fa76 commit f52f20e

File tree

1 file changed

+36
-10
lines changed

1 file changed

+36
-10
lines changed

src/client/app/composables/head.ts

+36-10
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,51 @@ import { HeadConfig, SiteData } from '../../shared'
33
import { Route } from '../router'
44

55
export function useUpdateHead(route: Route, siteDataByRouteRef: Ref<SiteData>) {
6-
const metaTags: HTMLElement[] = Array.from(document.querySelectorAll('meta'))
7-
6+
let metaTagEls: HTMLElement[] = Array.from(document.querySelectorAll('meta'))
87
let isFirstUpdate = true
8+
99
const updateHeadTags = (newTags: HeadConfig[]) => {
1010
if (import.meta.env.PROD && isFirstUpdate) {
1111
// in production, the initial meta tags are already pre-rendered so we
1212
// skip the first update.
1313
isFirstUpdate = false
1414
return
1515
}
16-
metaTags.forEach((el) => document.head.removeChild(el))
17-
metaTags.length = 0
18-
if (newTags && newTags.length) {
19-
newTags.forEach((headConfig) => {
20-
const el = createHeadElement(headConfig)
21-
document.head.appendChild(el)
22-
metaTags.push(el)
23-
})
16+
17+
const newEls: HTMLElement[] = []
18+
const commonLength = Math.min(metaTagEls.length, newTags.length)
19+
for (let i = 0; i < commonLength; i++) {
20+
let el = metaTagEls[i]
21+
const [tag, attrs] = newTags[i]
22+
if (el.tagName.toLocaleLowerCase() === tag) {
23+
for (const key in attrs) {
24+
if (el.getAttribute(key) !== attrs[key]) {
25+
el.setAttribute(key, attrs[key])
26+
}
27+
}
28+
for (let i = 0; i < el.attributes.length; i++) {
29+
const name = el.attributes[i].name
30+
if (!(name in attrs)) {
31+
el.removeAttribute(name)
32+
}
33+
}
34+
} else {
35+
document.head.removeChild(el)
36+
el = createHeadElement(newTags[i])
37+
document.head.append(el)
38+
}
39+
newEls.push(el)
2440
}
41+
42+
metaTagEls
43+
.slice(commonLength)
44+
.forEach((el) => document.head.removeChild(el))
45+
newTags.slice(commonLength).forEach((headConfig) => {
46+
const el = createHeadElement(headConfig)
47+
document.head.appendChild(el)
48+
newEls.push(el)
49+
})
50+
metaTagEls = newEls
2551
}
2652

2753
watchEffect(() => {

0 commit comments

Comments
 (0)