diff --git a/__tests__/unit/shared/shared.test.ts b/__tests__/unit/shared/shared.test.ts new file mode 100644 index 000000000000..8e58438db55d --- /dev/null +++ b/__tests__/unit/shared/shared.test.ts @@ -0,0 +1,33 @@ +import { mergeHead } from 'shared/shared' + +describe('shared/shared', () => { + test('mergeHead uses id as the key regardless of attribute order', () => { + const result = mergeHead( + [['meta', { id: 'description', name: 'description', content: 'site' }]], + [['meta', { content: 'page', name: 'description', id: 'description' }]] + ) + + expect(result).toEqual([ + ['meta', { content: 'page', name: 'description', id: 'description' }] + ]) + }) + + test('mergeHead keeps meta tags with unique ids', () => { + const result = mergeHead([ + [ + 'meta', + { content: '/preview.png', property: 'og:image', id: 'og-image' } + ], + [ + 'meta', + { + content: '/preview.png', + property: 'og:image:url', + id: 'og-image-url' + } + ] + ]) + + expect(result).toHaveLength(2) + }) +}) diff --git a/docs/en/reference/site-config.md b/docs/en/reference/site-config.md index a9d9c4f178fe..66f5154bc520 100644 --- a/docs/en/reference/site-config.md +++ b/docs/en/reference/site-config.md @@ -248,6 +248,24 @@ type HeadConfig = | [string, Record, string] ``` +VitePress uses the first attribute of each `meta` element as its key when merging `head` entries. To keep entries with identical first attributes, or to make the key independent of attribute order, give each entry a unique `id`. When present, `id` is used as the key regardless of its position in the attributes object. + +```ts +export default { + head: [ + ['meta', { content: '/preview.png', property: 'og:image', id: 'og-image' }], + [ + 'meta', + { + content: '/preview.png', + property: 'og:image:url', + id: 'og-image-url' + } + ] + ] +} +``` + #### Example: Adding a favicon ```ts diff --git a/src/shared/shared.ts b/src/shared/shared.ts index e7fda629f946..bf098b51ad69 100644 --- a/src/shared/shared.ts +++ b/src/shared/shared.ts @@ -203,7 +203,8 @@ export function mergeHead(...headArrays: HeadConfig[][]): HeadConfig[] { for (const current of headArrays) { for (const tag of current) { const [type, attrs] = tag - const keyAttr = Object.entries(attrs)[0] + const entries = Object.entries(attrs) + const keyAttr = entries.find(([name]) => name === 'id') ?? entries[0] if (type !== 'meta' || !keyAttr) { merged.push(tag)