From acb98a6d389740971a52e29d1434858b3dbd8ade Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Sat, 9 Dec 2023 04:12:47 +1100 Subject: [PATCH] fix: nuxt content merging --- src/runtime/nitro/plugins/nuxt-content.ts | 6 +++-- .../plugins/og-image-canonical-urls.server.ts | 25 ++++++++++++++++--- test/fixtures/content/app.vue | 11 ++++++++ test/fixtures/content/content/disabled.md | 5 ++++ test/fixtures/content/content/index.md | 2 -- 5 files changed, 41 insertions(+), 8 deletions(-) create mode 100644 test/fixtures/content/content/disabled.md diff --git a/src/runtime/nitro/plugins/nuxt-content.ts b/src/runtime/nitro/plugins/nuxt-content.ts index b379775b..88e6a747 100644 --- a/src/runtime/nitro/plugins/nuxt-content.ts +++ b/src/runtime/nitro/plugins/nuxt-content.ts @@ -1,6 +1,7 @@ import { defineNitroPlugin } from 'nitropack/dist/runtime/plugin' import type { ParsedContent } from '@nuxt/content/dist/runtime/types' import { defu } from 'defu' +import type { UseHeadInput } from 'unhead' import { getOgImagePath, useOgImageRuntimeConfig } from '../../utils' export default defineNitroPlugin((nitroApp) => { @@ -28,15 +29,16 @@ export default defineNitroPlugin((nitroApp) => { payload[key.replace(/-([a-z])/g, g => g[1].toUpperCase())] = val }) - content.head = defu({ + content.head = defu(> { script: [ { - id: 'nuxt-og-image-options', + id: 'nuxt-og-image-overrides', type: 'application/json', processTemplateParams: true, innerHTML: payload, // we want this to be last in our head tagPosition: 'bodyClose', + tagPriority: 30, // slighty higher priority }, ], meta: [ diff --git a/src/runtime/nuxt/plugins/og-image-canonical-urls.server.ts b/src/runtime/nuxt/plugins/og-image-canonical-urls.server.ts index 63af73db..5823465b 100644 --- a/src/runtime/nuxt/plugins/og-image-canonical-urls.server.ts +++ b/src/runtime/nuxt/plugins/og-image-canonical-urls.server.ts @@ -1,7 +1,9 @@ import { parseURL } from 'ufo' import type { HeadPlugin } from '@unhead/schema' import { toValue } from 'vue' -import { isInternalRoute } from '../../utils.pure' +import { defu } from 'defu' +import { isInternalRoute, separateProps } from '../../utils.pure' +import type { OgImageOptions } from '../../types' import { defineNuxtPlugin, useRequestEvent, withSiteUrl } from '#imports' export default defineNuxtPlugin({ @@ -16,10 +18,21 @@ export default defineNuxtPlugin({ // unhead plugin to correct missing site URL, this is to fix the Nuxt Content integration not being able to resolve the correct URL ssrContext?.head.use({ - key: 'nuxt-og-image:canonical-urls', + key: 'nuxt-og-image:overrides-and-canonical-urls', hooks: { - 'tags:resolve': async ({ tags }) => { - for (const tag of tags) { + 'tags:resolve': async (ctx) => { + // see if id "nuxt-og-image-overrides" exists + let overrides: OgImageOptions | undefined + for (const tag of ctx.tags) { + if (tag.tag === 'script' && tag.props.id === 'nuxt-og-image-overrides') { + overrides = separateProps(JSON.parse(tag.innerHTML || '{}')) + delete ctx.tags[ctx.tags.indexOf(tag)] + break + } + } + ctx.tags = ctx.tags.filter(Boolean) + + for (const tag of ctx.tags) { if (tag.tag === 'meta' && (tag.props.property === 'og:image' || tag.props.name === 'twitter:image:src')) { // looking for: // property og:image @@ -30,6 +43,10 @@ export default defineNuxtPlugin({ }) } } + // need to insert the overrides into the payload + else if (overrides && tag.tag === 'script' && tag.props.id === 'nuxt-og-image-options') { + tag.innerHTML = JSON.stringify(defu(overrides, JSON.parse(tag.innerHTML))) + } } }, }, diff --git a/test/fixtures/content/app.vue b/test/fixtures/content/app.vue index dfdd93c9..70984c23 100644 --- a/test/fixtures/content/app.vue +++ b/test/fixtures/content/app.vue @@ -1,3 +1,14 @@ + +