From d046c9620b3a25fba7ba08351e2cebe58da3b626 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 15 Feb 2022 09:50:40 +0000 Subject: [PATCH] feat(bridge): add support for `useNuxt2Meta` in plugins (#3187) --- packages/bridge/src/runtime/composables.ts | 69 ++++++++++++++-------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/packages/bridge/src/runtime/composables.ts b/packages/bridge/src/runtime/composables.ts index 24cd287b93..4356b64cb8 100644 --- a/packages/bridge/src/runtime/composables.ts +++ b/packages/bridge/src/runtime/composables.ts @@ -4,6 +4,7 @@ import type { MetaInfo } from 'vue-meta' import type VueRouter from 'vue-router' import type { Route } from 'vue-router' import type { RuntimeConfig } from '@nuxt/schema' +import defu from 'defu' import { useNuxtApp } from './app' export { useLazyAsyncData } from './asyncData' @@ -90,35 +91,53 @@ type AugmentedComponent = CombinedVueInstance | (() => Reffed)) { + return metaOptions instanceof Function ? metaOptions : () => metaOptions +} + export const useNuxt2Meta = (metaOptions: Reffed | (() => Reffed)) => { - const vm = getCurrentInstance()!.proxy as AugmentedComponent - const meta = vm.$meta() - const $root = vm.$root + let vm: AugmentedComponent | null = null + try { + vm = getCurrentInstance()!.proxy as AugmentedComponent + const meta = vm.$meta() + const $root = vm.$root - if (!vm._vueMeta) { - vm._vueMeta = true + if (!vm._vueMeta) { + vm._vueMeta = true - let parent = vm.$parent as AugmentedComponent - while (parent && parent !== $root) { - if (parent._vueMeta === undefined) { - parent._vueMeta = false + let parent = vm.$parent as AugmentedComponent + while (parent && parent !== $root) { + if (parent._vueMeta === undefined) { + parent._vueMeta = false + } + parent = parent.$parent } - parent = parent.$parent + } + // @ts-ignore + vm.$options.head = vm.$options.head || {} + + const unwatch = watch(metaInfoFromOptions(metaOptions), (metaInfo: MetaInfo) => { + vm.$metaInfo = { + ...vm.$metaInfo || {}, + ...unwrap(metaInfo) + } + if (process.client) { + meta.refresh() + } + }, { immediate: true, deep: true }) + + onBeforeUnmount(unwatch) + } catch { + const app = (useNuxtApp().nuxt2Context as any).app + if (typeof app.head === 'function') { + const originalHead = app.head + app.head = function () { + const head = originalHead.call(this) || {} + return defu(unwrap(metaInfoFromOptions(metaOptions)), head) + } + } else { + app.head = defu(unwrap(metaInfoFromOptions(metaOptions)), app.head) } } - // @ts-ignore - vm.$options.head = vm.$options.head || {} - - const metaSource = metaOptions instanceof Function ? metaOptions : () => metaOptions - const unwatch = watch(metaSource, (metaInfo: MetaInfo) => { - vm.$metaInfo = { - ...vm.$metaInfo || {}, - ...unwrap(metaInfo) - } - if (process.client) { - meta.refresh() - } - }, { immediate: true, deep: true }) - - onBeforeUnmount(unwatch) }