From f711046171ae758b81ea136593405d9f6753c817 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Tue, 24 Jan 2023 15:34:20 +0000 Subject: [PATCH] perf(nuxt): add tree-shaken `useServerSeoMeta` composable (#18476) --- .../1.docs/1.getting-started/5.seo-meta.md | 25 +++++-------------- packages/nuxt/src/head/module.ts | 9 +------ packages/nuxt/src/head/runtime/composables.ts | 25 +++++++++++++++++++ packages/nuxt/src/imports/presets.ts | 4 ++- 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/docs/content/1.docs/1.getting-started/5.seo-meta.md b/docs/content/1.docs/1.getting-started/5.seo-meta.md index 38054d961d..01f819ee88 100644 --- a/docs/content/1.docs/1.getting-started/5.seo-meta.md +++ b/docs/content/1.docs/1.getting-started/5.seo-meta.md @@ -70,19 +70,21 @@ useHead({ ::ReadMore{link="/docs/api/composables/use-head"} :: -## Composable: `useSeoMeta` +## Composable: `useSeoMeta` and `useServerSeoMeta` -The `useSeoMeta` composable lets you define your site's SEO meta tags as a flat object with full TypeScript support. +The `useSeoMeta` and `useServerSeoMeta` composables let you define your site's SEO meta tags as a flat object with full TypeScript support. This helps you avoid typos and common mistakes, such as using `name` instead of `property`. +In most instances, the meta does not need to be reactive as robots will only scan the initial load. So we recommend using `useServerSeoMeta` as a performance-focused utility that will not do anything (or return a `head` object) on the client. + ### Example #### Simple ```vue{}[app.vue] ``` -### Client-side Optimization - -In most instances, the meta does not need to be reactive as robots will only scan the initial load. - -The composable itself is ~2kB, so you may consider only using it on the server and having it be tree-shaken from the client bundle. - -```vue{}[app.vue] - -``` - ::ReadMore{link="https://unhead.harlanzw.com/guide/guides/useseometa"} :: diff --git a/packages/nuxt/src/head/module.ts b/packages/nuxt/src/head/module.ts index 5e7b811c39..e83ab330c7 100644 --- a/packages/nuxt/src/head/module.ts +++ b/packages/nuxt/src/head/module.ts @@ -1,5 +1,5 @@ import { resolve } from 'pathe' -import { addComponent, addImportsSources, addPlugin, defineNuxtModule } from '@nuxt/kit' +import { addComponent, addPlugin, defineNuxtModule } from '@nuxt/kit' import { distDir } from '../dirs' const components = ['NoScript', 'Link', 'Base', 'Title', 'Meta', 'Style', 'Head', 'Html', 'Body'] @@ -17,13 +17,6 @@ export default defineNuxtModule({ // Add #head alias nuxt.options.alias['#head'] = runtimeDir - addImportsSources({ - from: '@vueuse/head', - imports: [ - 'useSeoMeta' - ] - }) - // Register components const componentsPath = resolve(runtimeDir, 'components') for (const componentName of components) { diff --git a/packages/nuxt/src/head/runtime/composables.ts b/packages/nuxt/src/head/runtime/composables.ts index c92a6c7356..460cdd0d65 100644 --- a/packages/nuxt/src/head/runtime/composables.ts +++ b/packages/nuxt/src/head/runtime/composables.ts @@ -1,5 +1,6 @@ import type { HeadEntryOptions, UseHeadInput, ActiveHeadEntry } from '@vueuse/head' import type { HeadAugmentations } from '@nuxt/schema' +import { useSeoMeta as _useSeoMeta } from '@vueuse/head' import { useNuxtApp } from '#app' /** @@ -12,3 +13,27 @@ import { useNuxtApp } from '#app' export function useHead (input: UseHeadInput, options?: HeadEntryOptions): ActiveHeadEntry> | void { return useNuxtApp()._useHead(input, options) } + +/** + * The `useSeoMeta` composable lets you define your site's SEO meta tags + * as a flat object with full TypeScript support. + * + * This helps you avoid typos and common mistakes, such as using `name` + * instead of `property`. + * + * It is advised to use `useServerSeoMeta` unless you _need_ client-side + * rendering of your SEO meta tags. + */ +export const useSeoMeta: typeof _useSeoMeta = (meta) => { + return _useSeoMeta(meta) +} + +/** + * The `useServerSeoMeta` composable is identical to `useSeoMeta` except that + * it will have no effect (and will return nothing) if called on the client. + */ +export const useServerSeoMeta: typeof _useSeoMeta = (meta) => { + if (process.server) { + return _useSeoMeta(meta) + } +} diff --git a/packages/nuxt/src/imports/presets.ts b/packages/nuxt/src/imports/presets.ts index 37662beaec..b4065b9629 100644 --- a/packages/nuxt/src/imports/presets.ts +++ b/packages/nuxt/src/imports/presets.ts @@ -6,7 +6,9 @@ const commonPresets: InlinePreset[] = [ defineUnimportPreset({ from: '#head', imports: [ - 'useHead' + 'useHead', + 'useSeoMeta', + 'useServerSeoMeta' ] }), // vue-demi (mocked)