diff --git a/docs/content/3.api/1.composables/use-head.md b/docs/content/3.api/1.composables/use-head.md index 8fb170a0df2..4a96f0b8388 100644 --- a/docs/content/3.api/1.composables/use-head.md +++ b/docs/content/3.api/1.composables/use-head.md @@ -4,11 +4,9 @@ description: useHead customizes the head properties of individual pages of your # `useHead` -Nuxt provides the `useHead` composable to add and customize the head properties of individual pages of your Nuxt app. It uses [@vueuse/head](https://github.com/vueuse/head) under the hood. +Nuxt provides the `useHead` composable to add and customize the head properties of individual pages of your Nuxt app. -::alert{icon=👉} -`useHead` only works during `setup` or `Lifecycle Hooks`. -:: +`useHead` is powered by [@vueuse/head](https://github.com/vueuse/head), you can find more in-depth documentation [here](https://unhead.harlanzw.com/) ::ReadMore{link="/getting-started/seo-meta"} :: @@ -19,7 +17,7 @@ Nuxt provides the `useHead` composable to add and customize the head properties useHead(meta: MaybeComputedRef): void ``` -Below are the non-reactive types for `useMeta`. See [zhead](https://github.com/harlan-zw/zhead/tree/main/packages/schema/src) for more detailed types. +Below are the non-reactive types for `useHead`. See [zhead](https://github.com/harlan-zw/zhead/tree/main/packages/schema/src) for more detailed types. ```ts interface MetaObject { diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 343be8adac1..d27712f3bea 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -44,7 +44,9 @@ "@nuxt/vite-builder": "3.0.0-rc.13", "@vue/reactivity": "^3.2.45", "@vue/shared": "^3.2.45", - "@vueuse/head": "~1.0.0-rc.14", + "@vueuse/head": "^1.0.13", + "unhead": "^0.6.7", + "@unhead/ssr": "^0.6.7", "chokidar": "^3.5.3", "cookie-es": "^0.5.0", "defu": "^6.1.0", diff --git a/packages/nuxt/src/core/nitro.ts b/packages/nuxt/src/core/nitro.ts index 3d3797cdc26..43e918464c9 100644 --- a/packages/nuxt/src/core/nitro.ts +++ b/packages/nuxt/src/core/nitro.ts @@ -9,6 +9,8 @@ import defu from 'defu' import fsExtra from 'fs-extra' import { dynamicEventHandler } from 'h3' import type { Plugin } from 'rollup' +import { createHeadCore } from 'unhead' +import { renderSSRHead } from '@unhead/ssr' import { distDir } from '../dirs' import { ImportProtectionPlugin } from './plugins/import-protection' @@ -122,6 +124,12 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { } }) + // Add head chunk for SPA renders + const head = createHeadCore() + head.push(nuxt.options.app.head) + const headChunk = await renderSSRHead(head) + nitroConfig.virtual!['#head-static'] = `export default ${JSON.stringify(headChunk)}` + // Add fallback server for `ssr: false` if (!nuxt.options.ssr) { nitroConfig.virtual!['#build/dist/server/server.mjs'] = 'export default () => {}' diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 89d13c69c88..0b01f1b2e04 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -41,6 +41,9 @@ const getClientManifest: () => Promise = () => import('#build/dist/ser .then(r => r.default || r) .then(r => typeof r === 'function' ? r() : r) as Promise +// @ts-ignore +const getStaticRenderedHead = () : Promise => import('#head-static').then(r => r.default || r) + // @ts-ignore const getServerEntry = () => import('#build/dist/server/server.mjs').then(r => r.default || r) @@ -102,7 +105,7 @@ const getSPARenderer = lazyCachedFunction(async () => { data: {}, state: {} } - ssrContext!.renderMeta = ssrContext!.renderMeta ?? (() => ({})) + ssrContext!.renderMeta = ssrContext!.renderMeta ?? getStaticRenderedHead return Promise.resolve(result) } diff --git a/packages/nuxt/src/head/runtime/composables.ts b/packages/nuxt/src/head/runtime/composables.ts index 9516ede023a..c92a6c7356e 100644 --- a/packages/nuxt/src/head/runtime/composables.ts +++ b/packages/nuxt/src/head/runtime/composables.ts @@ -1,5 +1,5 @@ -import type { MetaObject } from '@nuxt/schema' -import type { MaybeComputedRef } from '@vueuse/head' +import type { HeadEntryOptions, UseHeadInput, ActiveHeadEntry } from '@vueuse/head' +import type { HeadAugmentations } from '@nuxt/schema' import { useNuxtApp } from '#app' /** @@ -9,6 +9,6 @@ import { useNuxtApp } from '#app' * Alternatively, for reactive meta state, you can pass in a function * that returns a meta object. */ -export function useHead (meta: MaybeComputedRef) { - useNuxtApp()._useHead(meta) +export function useHead (input: UseHeadInput, options?: HeadEntryOptions): ActiveHeadEntry> | void { + return useNuxtApp()._useHead(input, options) } diff --git a/packages/nuxt/src/head/runtime/index.ts b/packages/nuxt/src/head/runtime/index.ts index 6c8caa85f6a..a8f5fb9bed3 100644 --- a/packages/nuxt/src/head/runtime/index.ts +++ b/packages/nuxt/src/head/runtime/index.ts @@ -1,2 +1,6 @@ +import type { UseHeadInput } from '@vueuse/head' +import type { HeadAugmentations } from '@nuxt/schema' + export * from './composables' -export type { MetaObject } from '@nuxt/schema' + +export type MetaObject = UseHeadInput diff --git a/packages/nuxt/src/head/runtime/lib/vueuse-head.plugin.ts b/packages/nuxt/src/head/runtime/lib/vueuse-head.plugin.ts index 1b2c412ffc2..b10708b7907 100644 --- a/packages/nuxt/src/head/runtime/lib/vueuse-head.plugin.ts +++ b/packages/nuxt/src/head/runtime/lib/vueuse-head.plugin.ts @@ -1,63 +1,39 @@ -import type { HeadEntryOptions, MaybeComputedRef } from '@vueuse/head' -import { createHead, renderHeadToString } from '@vueuse/head' -import { onBeforeUnmount, getCurrentInstance } from 'vue' -import type { MetaObject } from '@nuxt/schema' -import { defineNuxtPlugin, useRouter } from '#app' +import { createHead, useHead } from '@vueuse/head' +import { defineNuxtPlugin } from '#app' // @ts-expect-error untyped import { appHead } from '#build/nuxt.config.mjs' export default defineNuxtPlugin((nuxtApp) => { const head = createHead() - - head.addEntry(appHead, { resolved: true }) + head.push(appHead) nuxtApp.vueApp.use(head) if (process.client) { // pause dom updates until page is ready and between page transitions let pauseDOMUpdates = true - head.hooks['before:dom'].push(() => !pauseDOMUpdates) - nuxtApp.hooks.hookOnce('app:mounted', () => { + const unpauseDom = () => { pauseDOMUpdates = false - head.updateDOM() - - // start pausing DOM updates when route changes (trigger immediately) - useRouter().beforeEach(() => { - pauseDOMUpdates = true - }) - // watch for new route before unpausing dom updates (triggered after suspense resolved) - useRouter().afterEach(() => { - // only if we have paused (clicking on a link to the current route triggers this) - if (pauseDOMUpdates) { - pauseDOMUpdates = false - head.updateDOM() - } - }) - }) - } - - nuxtApp._useHead = (_meta: MaybeComputedRef, options: HeadEntryOptions) => { - if (process.server) { - head.addEntry(_meta, options) - return + // triggers dom update + head.internalHooks.callHook('entries:updated', head.unhead) } - - const cleanUp = head.addReactiveEntry(_meta, options) - - const vm = getCurrentInstance() - if (!vm) { return } - - onBeforeUnmount(() => { - cleanUp() - head.updateDOM() - }) + head.internalHooks.hook('dom:beforeRender', (context) => { context.shouldRender = !pauseDOMUpdates }) + nuxtApp.hooks.hook('page:start', () => { pauseDOMUpdates = true }) + // wait for new page before unpausing dom updates (triggered after suspense resolved) + nuxtApp.hooks.hook('page:finish', unpauseDom) + nuxtApp.hooks.hook('app:mounted', unpauseDom) } + // useHead does not depend on a vue component context, we keep it on the nuxtApp for backwards compatibility + nuxtApp._useHead = useHead + if (process.server) { nuxtApp.ssrContext!.renderMeta = async () => { - const meta = await renderHeadToString(head) + const { renderSSRHead } = await import('@unhead/ssr') + const meta = await renderSSRHead(head.unhead) return { ...meta, + bodyScriptsPrepend: meta.bodyTagsOpen, // resolves naming difference with NuxtMeta and @vueuse/head bodyScripts: meta.bodyTags } diff --git a/packages/schema/build.config.ts b/packages/schema/build.config.ts index 6ae914a75db..7c23363f783 100644 --- a/packages/schema/build.config.ts +++ b/packages/schema/build.config.ts @@ -22,7 +22,7 @@ export default defineBuildConfig({ 'vue-meta', 'vue-router', 'vue-bundle-renderer', - '@vueuse/head', + '@unhead/schema', 'vue', 'hookable', 'nitropack', diff --git a/packages/schema/package.json b/packages/schema/package.json index bad50e5f1f7..5cb31d5333a 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -17,7 +17,7 @@ "@types/lodash.template": "^4", "@types/semver": "^7", "@vitejs/plugin-vue": "^3.2.0", - "@vueuse/head": "~1.0.0-rc.14", + "@unhead/schema": "^0.6.7", "nitropack": "^1.0.0-0", "unbuild": "latest", "vite": "~3.2.3" diff --git a/packages/schema/src/types/meta.ts b/packages/schema/src/types/meta.ts index d79bfe55b72..03d0dce13ca 100644 --- a/packages/schema/src/types/meta.ts +++ b/packages/schema/src/types/meta.ts @@ -1,6 +1,6 @@ -import type { HeadObjectPlain, HeadObject } from '@vueuse/head' +import type { Head, MergeHead } from '@unhead/schema' -export interface HeadAugmentations { +export interface HeadAugmentations extends MergeHead { // runtime type modifications base?: {} link?: {} @@ -12,7 +12,8 @@ export interface HeadAugmentations { bodyAttrs?: {} } -export type MetaObjectRaw = HeadObjectPlain +export type MetaObjectRaw = Head +export type MetaObject = MetaObjectRaw export type AppHeadMetaObject = MetaObjectRaw & { /** @@ -29,70 +30,3 @@ export type AppHeadMetaObject = MetaObjectRaw & { */ viewport?: string } - -export interface MetaObject { - /** - * The HTML element defines the document's title that is shown in a browser's title bar or a page's tab. - * It only contains text; tags within the element are ignored. - * - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title - */ - title?: HeadObject<HeadAugmentations>['title'] - /** - * Generate the title from a template. - */ - titleTemplate?: HeadObject<HeadAugmentations>['titleTemplate'] - /** - * The <base> HTML element specifies the base URL to use for all relative URLs in a document. - * There can be only one <base> element in a document. - * - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base - */ - base?: HeadObject<HeadAugmentations>['base'] - /** - * The <link> HTML element specifies relationships between the current document and an external resource. - * This element is most commonly used to link to stylesheets, but is also used to establish site icons - * (both "favicon" style icons and icons for the home screen and apps on mobile devices) among other things. - * - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#attr-as - */ - link?: HeadObject<HeadAugmentations>['link'] - /** - * The <meta> element represents metadata that cannot be expressed in other HTML elements, like <link> or <script>. - * - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta - */ - meta?: HeadObject<HeadAugmentations>['meta'] - /** - * The <style> HTML element contains style information for a document, or part of a document. - * It contains CSS, which is applied to the contents of the document containing the <style> element. - * - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style - */ - style?: HeadObject<HeadAugmentations>['style'] - /** - * The <script> HTML element is used to embed executable code or data; this is typically used to embed or refer to JavaScript code. - * - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script - */ - script?: HeadObject<HeadAugmentations>['script'] - /** - * The <noscript> HTML element defines a section of HTML to be inserted if a script type on the page is unsupported - * or if scripting is currently turned off in the browser. - * - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/noscript - */ - noscript?: HeadObject<HeadAugmentations>['noscript'] - /** - * Attributes for the <html> HTML element. - * - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/html - */ - htmlAttrs?: HeadObject<HeadAugmentations>['htmlAttrs'] - /** - * Attributes for the <body> HTML element. - * - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body - */ - bodyAttrs?: HeadObject<HeadAugmentations>['bodyAttrs'] -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 245ff997f33..e332b50d254 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -417,9 +417,10 @@ importers: '@nuxt/vite-builder': workspace:* '@types/fs-extra': ^9.0.13 '@types/hash-sum': ^1.0.0 + '@unhead/ssr': ^0.6.7 '@vue/reactivity': ^3.2.45 '@vue/shared': ^3.2.45 - '@vueuse/head': ~1.0.0-rc.14 + '@vueuse/head': ^1.0.13 chokidar: ^3.5.3 cookie-es: ^0.5.0 defu: ^6.1.0 @@ -447,6 +448,7 @@ importers: unbuild: ^0.9.4 unctx: ^2.0.2 unenv: ^1.0.0 + unhead: ^0.6.7 unimport: ^1.0.0 unplugin: ^0.10.2 untyped: ^0.5.0 @@ -462,9 +464,10 @@ importers: '@nuxt/telemetry': 2.1.6 '@nuxt/ui-templates': 0.4.0 '@nuxt/vite-builder': link:../vite + '@unhead/ssr': 0.6.7 '@vue/reactivity': 3.2.45 '@vue/shared': 3.2.45 - '@vueuse/head': 1.0.0-rc.14_vue@3.2.45 + '@vueuse/head': 1.0.13_vue@3.2.45 chokidar: 3.5.3 cookie-es: 0.5.0 defu: 6.1.0 @@ -491,6 +494,7 @@ importers: ultrahtml: 1.0.0 unctx: 2.0.2 unenv: 1.0.0 + unhead: 0.6.7 unimport: 1.0.0 unplugin: 0.10.2 untyped: 0.5.0 @@ -508,8 +512,8 @@ importers: specifiers: '@types/lodash.template': ^4 '@types/semver': ^7 + '@unhead/schema': ^0.6.7 '@vitejs/plugin-vue': ^3.2.0 - '@vueuse/head': ~1.0.0-rc.14 c12: ^1.0.1 create-require: ^1.1.1 defu: ^6.1.0 @@ -541,8 +545,8 @@ importers: devDependencies: '@types/lodash.template': 4.5.1 '@types/semver': 7.3.12 + '@unhead/schema': 0.6.7 '@vitejs/plugin-vue': 3.2.0_vite@3.2.3 - '@vueuse/head': 1.0.0-rc.14 nitropack: 1.0.0-0 unbuild: 0.9.4 vite: 3.2.3 @@ -2099,6 +2103,34 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /@unhead/dom/0.6.7: + resolution: {integrity: sha512-HUp8ygfQ7VfpEouy26nLsuk6Y5ii5UldoC1NdTuzHSxkYwlq0v4rMpiO1f7T/0i9D7RJDpAp8LdhsHKgcEmRiA==} + dependencies: + '@unhead/schema': 0.6.7 + dev: false + + /@unhead/schema/0.6.7: + resolution: {integrity: sha512-wVf3Zu7deua63J/HYKoUXUkG0wZLPnKws1DNpSJkhNrjbpdzvsfI08lPIkW1ISqddQiLFXOgcnbhYrhcD7ZZYw==} + dependencies: + '@zhead/schema': 1.0.0-beta.13 + hookable: 5.4.1 + + /@unhead/ssr/0.6.7: + resolution: {integrity: sha512-jvEJER7dMSEtI6u60OrEz4gwhmQDGbo086HXdIYoT7RoaJ/YQa/CUAHRfLTO6F657iYs42VPFM3yRCVUbexZhA==} + dependencies: + '@unhead/schema': 0.6.7 + dev: false + + /@unhead/vue/0.6.7_vue@3.2.45: + resolution: {integrity: sha512-9qQ90WtOoQpXihM/MzDHiLWZ53HcZg9Xynf8PhY+004wLfj9e2cE2jSms1mjdP+BC7wVoeENQ9NCv4fOa6l6MQ==} + peerDependencies: + vue: '>=2.7 || >=3' + dependencies: + '@unhead/schema': 0.6.7 + hookable: 5.4.1 + vue: 3.2.45 + dev: false + /@unocss/astro/0.45.25: resolution: {integrity: sha512-TxFxESIvSZtaVIRP/cDyrwnYlHz78mG9ohhAhI0adLGi0v0yBwoGJ1krlqxAuTzhV191InTlwD/C5QevTsf86Q==} dependencies: @@ -2562,29 +2594,16 @@ packages: - vue dev: true - /@vueuse/head/1.0.0-rc.14: - resolution: {integrity: sha512-3DtOfSE1141IKPIq4AR5UXQZPWQFSd7E5f3M+HkBRyxWsyxbNBBmK5hqkSYc2ENoFXa3xPhLYZXJPKuxqfJmiA==} + /@vueuse/head/1.0.13_vue@3.2.45: + resolution: {integrity: sha512-QJ69f+V0blbroHPuOAYBQZek31kMmFttgUj+QmL+rnXgFUfRXj5rqIDC2chFBSsjHcWl6KfzwPbou5mjCVJAgw==} peerDependencies: vue: '>=2.7 || >=3' dependencies: - '@vueuse/shared': 9.4.0 - '@zhead/schema': 0.9.9 - '@zhead/schema-vue': 0.9.9 - transitivePeerDependencies: - - '@vue/composition-api' - dev: true - - /@vueuse/head/1.0.0-rc.14_vue@3.2.45: - resolution: {integrity: sha512-3DtOfSE1141IKPIq4AR5UXQZPWQFSd7E5f3M+HkBRyxWsyxbNBBmK5hqkSYc2ENoFXa3xPhLYZXJPKuxqfJmiA==} - peerDependencies: - vue: '>=2.7 || >=3' - dependencies: - '@vueuse/shared': 9.4.0_vue@3.2.45 - '@zhead/schema': 0.9.9 - '@zhead/schema-vue': 0.9.9_vue@3.2.45 + '@unhead/dom': 0.6.7 + '@unhead/schema': 0.6.7 + '@unhead/ssr': 0.6.7 + '@unhead/vue': 0.6.7_vue@3.2.45 vue: 3.2.45 - transitivePeerDependencies: - - '@vue/composition-api' dev: false /@vueuse/integrations/9.3.0_focus-trap@7.0.0: @@ -2660,24 +2679,6 @@ packages: - vue dev: true - /@vueuse/shared/9.4.0: - resolution: {integrity: sha512-fTuem51KwMCnqUKkI8B57qAIMcFovtGgsCtAeqxIzH3i6nE9VYge+gVfneNHAAy7lj8twbkNfqQSygOPJTm4tQ==} - dependencies: - vue-demi: 0.13.11 - transitivePeerDependencies: - - '@vue/composition-api' - - vue - dev: true - - /@vueuse/shared/9.4.0_vue@3.2.45: - resolution: {integrity: sha512-fTuem51KwMCnqUKkI8B57qAIMcFovtGgsCtAeqxIzH3i6nE9VYge+gVfneNHAAy7lj8twbkNfqQSygOPJTm4tQ==} - dependencies: - vue-demi: 0.13.11_vue@3.2.45 - transitivePeerDependencies: - - '@vue/composition-api' - - vue - dev: false - /@webassemblyjs/ast/1.11.1: resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} dependencies: @@ -2775,31 +2776,8 @@ packages: /@xtuc/long/4.2.2: resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - /@zhead/schema-vue/0.9.9: - resolution: {integrity: sha512-f7sOPMc1zQJ+tDDWWaksNsGoGGuRv5aHvOdZvsL3dIxbiHVlGVhDi/HZbUUupCtlYAPv2D8E/tUmwWKh/UrbXw==} - peerDependencies: - vue: '>=2.7 || >=3' - dependencies: - '@vueuse/shared': 9.4.0 - '@zhead/schema': 0.9.9 - transitivePeerDependencies: - - '@vue/composition-api' - dev: true - - /@zhead/schema-vue/0.9.9_vue@3.2.45: - resolution: {integrity: sha512-f7sOPMc1zQJ+tDDWWaksNsGoGGuRv5aHvOdZvsL3dIxbiHVlGVhDi/HZbUUupCtlYAPv2D8E/tUmwWKh/UrbXw==} - peerDependencies: - vue: '>=2.7 || >=3' - dependencies: - '@vueuse/shared': 9.4.0_vue@3.2.45 - '@zhead/schema': 0.9.9 - vue: 3.2.45 - transitivePeerDependencies: - - '@vue/composition-api' - dev: false - - /@zhead/schema/0.9.9: - resolution: {integrity: sha512-B/No5zsZB1gz6BT7OKcD0rbyZCGoF6ImeQm2ffupQrgUpYAIv/LGtn3RVNSOcX2R2DB4g79UtuIwK0OxugFjJQ==} + /@zhead/schema/1.0.0-beta.13: + resolution: {integrity: sha512-P1A1vRGFBhITco8Iw4/hvnDYoE/SoVrd71dW1pBFdXJb3vP+pBtoOuhbEKy0ROJGOyzQuqvFibcwzyLlWMqNiQ==} /abbrev/1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -6737,7 +6715,7 @@ packages: typescript: optional: true dependencies: - defu: 6.1.1 + defu: 6.1.0 esbuild: 0.14.54 fs-extra: 10.1.0 globby: 11.1.0 @@ -8730,6 +8708,14 @@ packages: node-fetch-native: 1.0.1 pathe: 1.0.0 + /unhead/0.6.7: + resolution: {integrity: sha512-YIVkGHHCUXbh0xFItqvJi08uk390ondXr+ge9lYwDiGQms8ykSGkDUbpMEXDrC8WnwoGXFkwaEZXRPIWx4ZxfA==} + dependencies: + '@unhead/dom': 0.6.7 + '@unhead/schema': 0.6.7 + hookable: 5.4.1 + dev: false + /unimport/1.0.0: resolution: {integrity: sha512-7M2+6uC6Ik3/imN0VhEBJGnnH5SWLPxhPAPKdMMIt2Bh+YW7F42aZFC9APW3h82r4bvS5qQWaMJko2G9m7SDYA==} dependencies: @@ -9221,21 +9207,6 @@ packages: optional: true dev: true - /vue-demi/0.13.11_vue@3.2.45: - resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - peerDependencies: - '@vue/composition-api': ^1.0.0-rc.1 - vue: ^3.0.0-0 || ^2.6.0 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - dependencies: - vue: 3.2.45 - dev: false - /vue-devtools-stub/0.1.0: resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==} dev: false diff --git a/test/basic.test.ts b/test/basic.test.ts index f5e50add652..f43b7305383 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -253,7 +253,7 @@ describe('head tags', () => { expect(headHtml).toContain('<meta name="description" content="overriding with an inline useHead call">') expect(headHtml).toMatch(/<html[^>]*class="html-attrs-test"/) expect(headHtml).toMatch(/<body[^>]*class="body-attrs-test"/) - expect(headHtml).toContain('<script src="https://a-body-appended-script.com" data-meta-body></script></body>') + expect(headHtml).toContain('<script src="https://a-body-appended-script.com"></script></body>') const indexHtml = await $fetch('/') // should render charset by default diff --git a/test/bundle.test.ts b/test/bundle.test.ts index 22e4ea5d22b..c0c2c80a384 100644 --- a/test/bundle.test.ts +++ b/test/bundle.test.ts @@ -52,6 +52,9 @@ describe.skipIf(isWindows)('minimal nuxt application', () => { expect(packages).toMatchInlineSnapshot(` [ "@babel/parser", + "@unhead/dom", + "@unhead/ssr", + "@unhead/vue", "@vue/compiler-core", "@vue/compiler-dom", "@vue/compiler-ssr", @@ -60,7 +63,6 @@ describe.skipIf(isWindows)('minimal nuxt application', () => { "@vue/runtime-dom", "@vue/server-renderer", "@vue/shared", - "@vueuse/shared", "buffer-from", "cookie-es", "destr", @@ -81,7 +83,6 @@ describe.skipIf(isWindows)('minimal nuxt application', () => { "unstorage", "vue", "vue-bundle-renderer", - "vue-demi", ] `) }) diff --git a/test/fixtures/basic/types.ts b/test/fixtures/basic/types.ts index 11ea9ea0c41..76c35236290 100644 --- a/test/fixtures/basic/types.ts +++ b/test/fixtures/basic/types.ts @@ -123,7 +123,6 @@ describe('runtimeConfig', () => { describe('head', () => { it('correctly types nuxt.config options', () => { - // @ts-expect-error defineNuxtConfig({ app: { head: { titleTemplate: () => 'test' } } }) defineNuxtConfig({ app: {