diff --git a/docs/content/3.api/3.utils/define-nuxt-component.md b/docs/content/3.api/3.utils/define-nuxt-component.md index 49c0960b9b6..d245c5b4bb6 100644 --- a/docs/content/3.api/3.utils/define-nuxt-component.md +++ b/docs/content/3.api/3.utils/define-nuxt-component.md @@ -5,10 +5,10 @@ description: defineNuxtComponent() is a helper function for defining type safe c # `defineNuxtComponent` -`defineNuxtComponent()` is a helper function for defining type safe Vue components using options API similar to [defineComponent()](https://vuejs.org/api/general.html#definecomponent). `defineNuxtComponent()` wrapper also adds support for `asyncData` component option. +`defineNuxtComponent()` is a helper function for defining type safe Vue components using options API similar to [defineComponent()](https://vuejs.org/api/general.html#definecomponent). `defineNuxtComponent()` wrapper also adds support for `asyncData` and `head` component options. ::alert{type=warning} -Options API support for `asyncData` may well change before the stable release of Nuxt 3. +Options API support for `asyncData` and `head` may well change before the stable release of Nuxt 3. :: ::Alert @@ -34,3 +34,19 @@ export default defineNuxtComponent({ }) ``` + +## `head()` + +If you choose not to use `setup()` in your app, you can use the `head()` method within your component definition: + +```vue [pages/index.vue] + +``` diff --git a/packages/nuxt/src/app/composables/component.ts b/packages/nuxt/src/app/composables/component.ts index bceff5e2322..bdd8b61ea1b 100644 --- a/packages/nuxt/src/app/composables/component.ts +++ b/packages/nuxt/src/app/composables/component.ts @@ -4,6 +4,9 @@ import { NuxtApp, useNuxtApp } from '../nuxt' import { useAsyncData } from './asyncData' import { useRoute } from './router' +// eslint-disable-next-line import/no-restricted-paths +import { useHead } from '#head' + export const NuxtComponentIndicator = '__nuxt_component' async function runLegacyAsyncData (res: Record | Promise>, fn: (nuxtApp: NuxtApp) => Promise>) { @@ -25,7 +28,7 @@ export const defineNuxtComponent: typeof defineComponent = const { setup } = options // Avoid wrapping if no options api is used - if (!setup && !options.asyncData) { + if (!setup && !options.asyncData && !options.head) { return { [NuxtComponentIndicator]: true, ...options @@ -43,6 +46,11 @@ export const defineNuxtComponent: typeof defineComponent = promises.push(runLegacyAsyncData(res, options.asyncData)) } + if (options.head) { + const nuxtApp = useNuxtApp() + useHead(typeof options.head === 'function' ? () => options.head(nuxtApp) : options.head) + } + return Promise.resolve(res) .then(() => Promise.all(promises)) .then(() => res) diff --git a/packages/nuxt/src/app/index.ts b/packages/nuxt/src/app/index.ts index 9920eb30e3b..37bd3f93a45 100644 --- a/packages/nuxt/src/app/index.ts +++ b/packages/nuxt/src/app/index.ts @@ -10,7 +10,7 @@ export type { PageMeta } from '../pages/runtime' // eslint-disable-next-line import/no-restricted-paths export type { MetaObject } from '../head/runtime' // eslint-disable-next-line import/no-restricted-paths -export { useHead, useMeta } from '#head' +export { useHead } from '#head' export const isVue2 = false export const isVue3 = true diff --git a/packages/nuxt/src/head/module.ts b/packages/nuxt/src/head/module.ts index 263ced169b3..b6993629be7 100644 --- a/packages/nuxt/src/head/module.ts +++ b/packages/nuxt/src/head/module.ts @@ -29,9 +29,6 @@ export default defineNuxtModule({ }) } - // Add mixin plugin - addPlugin({ src: resolve(runtimeDir, 'mixin-plugin') }) - // Add library specific plugin addPlugin({ src: resolve(runtimeDir, 'lib/vueuse-head.plugin') }) } diff --git a/packages/nuxt/src/head/runtime/composables.ts b/packages/nuxt/src/head/runtime/composables.ts index d404b4f2f09..9516ede023a 100644 --- a/packages/nuxt/src/head/runtime/composables.ts +++ b/packages/nuxt/src/head/runtime/composables.ts @@ -12,9 +12,3 @@ import { useNuxtApp } from '#app' export function useHead (meta: MaybeComputedRef) { useNuxtApp()._useHead(meta) } - -// TODO: remove useMeta support when Nuxt 3 is stable -/** @deprecated Please use new `useHead` composable instead */ -export function useMeta (meta: MaybeComputedRef) { - return useHead(meta) -} diff --git a/packages/nuxt/src/head/runtime/mixin-plugin.ts b/packages/nuxt/src/head/runtime/mixin-plugin.ts deleted file mode 100644 index 906211527be..00000000000 --- a/packages/nuxt/src/head/runtime/mixin-plugin.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { getCurrentInstance } from 'vue' -import { useHead } from './composables' -import { defineNuxtPlugin, useNuxtApp } from '#app' - -const metaMixin = { - created () { - const instance = getCurrentInstance() - if (!instance) { return } - - const options = instance.type - if (!options || !('head' in options)) { return } - - const nuxtApp = useNuxtApp() - const source = typeof options.head === 'function' - ? () => options.head(nuxtApp) - : options.head - - useHead(source) - } -} - -export default defineNuxtPlugin((nuxtApp) => { - nuxtApp.vueApp.mixin(metaMixin) -}) diff --git a/packages/nuxt/src/imports/presets.ts b/packages/nuxt/src/imports/presets.ts index 5c29c86eeed..0cdfff6d245 100644 --- a/packages/nuxt/src/imports/presets.ts +++ b/packages/nuxt/src/imports/presets.ts @@ -5,8 +5,7 @@ const commonPresets: InlinePreset[] = [ defineUnimportPreset({ from: '#head', imports: [ - 'useHead', - 'useMeta' + 'useHead' ] }), // vue-demi (mocked) diff --git a/test/basic.test.ts b/test/basic.test.ts index b1a9105930e..f5e50add652 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -253,7 +253,6 @@ describe('head tags', () => { expect(headHtml).toContain('') expect(headHtml).toMatch(/]*class="html-attrs-test"/) expect(headHtml).toMatch(/]*class="body-attrs-test"/) - expect(headHtml).toContain('script>console.log("works with useMeta too")') expect(headHtml).toContain('') const indexHtml = await $fetch('/') diff --git a/test/bundle.test.ts b/test/bundle.test.ts index 1ec71193e98..22e4ea5d22b 100644 --- a/test/bundle.test.ts +++ b/test/bundle.test.ts @@ -29,6 +29,7 @@ describe.skipIf(isWindows)('minimal nuxt application', () => { expect(stats.client.totalBytes).toBeLessThan(110000) expect(stats.client.files.map(f => f.replace(/\..*\.js/, '.js'))).toMatchInlineSnapshot(` [ + "_nuxt/composables.js", "_nuxt/entry.js", "_nuxt/error-404.js", "_nuxt/error-500.js", diff --git a/test/fixtures/basic/pages/head.vue b/test/fixtures/basic/pages/head.vue index ee3328b8a3f..58ce42d2668 100644 --- a/test/fixtures/basic/pages/head.vue +++ b/test/fixtures/basic/pages/head.vue @@ -1,35 +1,32 @@ - -