perf(nuxt): add tree-shaken useServerSeoMeta composable (#18476)

This commit is contained in:
Daniel Roe 2023-01-24 15:34:20 +00:00 committed by GitHub
parent eac787eb48
commit f711046171
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 28 deletions

View File

@ -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]
<script setup lang="ts">
useSeoMeta({
useServerSeoMeta({
title: 'My Amazing Site',
ogTitle: 'My Amazing Site',
description: 'This is my amazing site, let me tell you all about it.',
@ -101,7 +103,7 @@ use the computed getter syntax, the same as `useHead`.
```vue{}[app.vue]
<script setup lang="ts">
const data = useFetch(() => $fetch('/api/example'))
useSeoMeta({
useServerSeoMeta({
ogTitle: () => `${data.value?.title} - My Site`,
description: () => data.value?.description,
ogDescription: () => data.value?.description,
@ -109,21 +111,6 @@ useSeoMeta({
</script>
```
### 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]
<script setup lang="ts">
// only run on the server or in development mode
if (process.dev || process.server) {
useSeoMeta({ description: () => myDescription.value })
}
</script>
```
::ReadMore{link="https://unhead.harlanzw.com/guide/guides/useseometa"}
::

View File

@ -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) {

View File

@ -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<T extends HeadAugmentations> (input: UseHeadInput<T>, options?: HeadEntryOptions): ActiveHeadEntry<UseHeadInput<T>> | 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)
}
}

View File

@ -6,7 +6,9 @@ const commonPresets: InlinePreset[] = [
defineUnimportPreset({
from: '#head',
imports: [
'useHead'
'useHead',
'useSeoMeta',
'useServerSeoMeta'
]
}),
// vue-demi (mocked)