Skip to content

Commit

Permalink
refactor(nuxt3,bridge)!: rename useMeta to useHead (nuxt#4066)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe authored Apr 5, 2022
1 parent 7054b98 commit e90b8c2
Show file tree
Hide file tree
Showing 29 changed files with 163 additions and 81 deletions.
14 changes: 7 additions & 7 deletions docs/content/1.getting-started/4.bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,13 @@ If you want to use the new Nuxt composables (such as `useNuxtApp` or `useRuntime
Although a compatibility interface is provided via `nuxtApp.vueApp` you should avoid registering plugins, directives, mixins or components this way without adding your own logic to ensure they are not installed more than once, or this may cause a memory leak.
::

## New `useMeta` (optional)
## New `useHead` (optional)

Nuxt Bridge provides a new Nuxt 3 meta API that can be accessed with a new `useMeta` composable.
Nuxt Bridge provides a new Nuxt 3 meta API that can be accessed with a new `useHead` composable.

```vue
<script setup>
useMeta({
useHead({
title: 'My Nuxt App',
})
</script>
Expand All @@ -222,10 +222,10 @@ export default defineNuxtConfig({
})
```

This `useMeta` composable uses `@vueuse/head` under the hood (rather than `vue-meta`) to manipulate your `<head>`.
Accordingly, we recommend not to use both the native Nuxt 2 `head()` properties as well as `useMeta`, as they may conflict.
This `useHead` composable uses `@vueuse/head` under the hood (rather than `vue-meta`) to manipulate your `<head>`.
Accordingly, we recommend not to use both the native Nuxt 2 `head()` properties as well as `useHead`, as they may conflict.

For more information on how to use this composable, see [the docs](/docs/usage/meta-tags#usemeta-composable).
For more information on how to use this composable, see [the docs](/docs/usage/meta-tags#usehead-composable).

## Feature Flags

Expand All @@ -244,7 +244,7 @@ export default defineNuxtConfig({
// Use Vite as the bundler instead of webpack 4
// vite: true,

// Enable Nuxt 3 compatible useMeta
// Enable Nuxt 3 compatible useHead
// meta: true,

// -- Default features --
Expand Down
8 changes: 4 additions & 4 deletions docs/content/1.getting-started/5.bridge-composition-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,12 @@ title.value = 'new title'
Be careful not to use both `useNuxt2Meta()` and the Options API `head()` within the same component, as behavior may be unpredictable.
::

Nuxt Bridge also provides a Nuxt 3-compatible meta implementation that can be accessed with the `useMeta` composable.
Nuxt Bridge also provides a Nuxt 3-compatible meta implementation that can be accessed with the `useHead` composable.

```diff
<script setup>
- import { useMeta } from '@nuxtjs/composition-api'
useMeta({
useHead({
title: 'My Nuxt App',
})
</script>
Expand All @@ -272,6 +272,6 @@ export default defineNuxtConfig({
})
```

This `useMeta` composable uses `@vueuse/head` under the hood (rather than `vue-meta`) to manipulate your `<head>`. Accordingly, it is recommended not to use both the native Nuxt 2 `head()` properties as well as `useMeta`, as they may conflict.
This `useHead` composable uses `@vueuse/head` under the hood (rather than `vue-meta`) to manipulate your `<head>`. Accordingly, it is recommended not to use both the native Nuxt 2 `head()` properties as well as `useHead`, as they may conflict.

For more information on how to use this composable, see [the Nuxt 3 docs](/docs/usage/meta-tags#usemeta-composable).
For more information on how to use this composable, see [the Nuxt 3 docs](/docs/usage/meta-tags#usehead-composable).
10 changes: 5 additions & 5 deletions docs/content/3.docs/1.usage/3.meta-tags.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

You can customize the meta tags for your site through several different ways:

## `useMeta` Composable
## `useHead` Composable

Within your `setup` function, you can call `useMeta` with an object of meta properties with keys corresponding to meta tags: `title`, `base`, `script`, `style`, `meta` and `link`, as well as `htmlAttrs` and `bodyAttrs`. Alternatively, you can pass a function returning the object for reactive metadata.
Within your `setup` function, you can call `useHead` with an object of meta properties with keys corresponding to meta tags: `title`, `base`, `script`, `style`, `meta` and `link`, as well as `htmlAttrs` and `bodyAttrs`. Alternatively, you can pass a function returning the object for reactive metadata.

For example:

```js
export default {
setup () {
useMeta({
useHead({
meta: [
{ name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1' }
],
Expand Down Expand Up @@ -63,7 +63,7 @@ export default {

## Example: usage with definePageMeta

You can use `definePageMeta` along with `useMeta` to set metadata based on the current route.
You can use `definePageMeta` along with `useHead` to set metadata based on the current route.

For example, to include the page title alongside your app name, first define your page title:

Expand All @@ -81,7 +81,7 @@ And then in your layout file:
<script setup>
const route = useRoute()
useMeta({
useHead({
title: computed(() => `App Name - ${route.meta.title}`)
})
</script>
Expand Down
8 changes: 4 additions & 4 deletions docs/content/3.docs/3.migration/4.meta.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Nuxt 3 provides several different ways to manage your meta tags.

1. Through your `nuxt.config`.
1. Through the `useMeta` [composable](/docs/usage/meta-tags#usemeta-composable)
1. Through the `useHead` [composable](/docs/usage/meta-tags#usehead-composable)
1. Through [global meta components](/docs/usage/meta-tags#meta-components)

You can customize `title`, `base`, `script`, `style`, `meta`, `link`, `htmlAttrs` and `bodyAttrs`.
Expand All @@ -17,9 +17,9 @@ Nuxt currently uses [`vueuse/head`](https://github.com/vueuse/head) to manage yo
## Migration

1. In your `nuxt.config`, rename `head` to `meta`. Consider moving this shared meta configuration into your `app.vue` instead. (Note that objects no longer have a `hid` key for deduplication.)
1. In your components, rename your `head` option to `meta`. If you need to access the component state, you should migrate to using `useMeta`. You might also consider using the built-in meta-components.
1. If you need to access the component state with `head`, you should migrate to using `useHead`. You might also consider using the built-in meta-components.

### Example: `useMeta`
### Example: `useHead`

::code-group

Expand Down Expand Up @@ -50,7 +50,7 @@ const title = ref('My App')
const description = ref('My App Description')
// This will be reactive even you change title/description above
useMeta({
useHead({
title,
meta: [{
name: 'description',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
template: Example
---

# useMeta
# useHead

This example shows how to use `useMeta` and Nuxt built-in components to bind meta data to the head of the page.
This example shows how to use `useHead` and Nuxt built-in components to bind meta data to the head of the page.

::alert{type=info icon=👉}
Learn more about [meta tags](/docs/usage/meta-tags).
::

::sandbox{repo="nuxt/framework" branch="main" dir="examples/composables/use-meta" file="app.vue"}
::sandbox{repo="nuxt/framework" branch="main" dir="examples/composables/use-head" file="app.vue"}
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
| `use-async-data` | [GitHub](https://github.com/nuxt/framework/tree/main/examples/use-async-data) | [Play Online](https://stackblitz.com/github/nuxt/framework/tree/main/examples/use-async-data?file=app.vue&terminal=dev) |
| `use-cookie` | [GitHub](https://github.com/nuxt/framework/tree/main/examples/use-cookie) | [Play Online](https://stackblitz.com/github/nuxt/framework/tree/main/examples/use-cookie?file=app.vue&terminal=dev) |
| `use-fetch` | [GitHub](https://github.com/nuxt/framework/tree/main/examples/use-fetch) | [Play Online](https://stackblitz.com/github/nuxt/framework/tree/main/examples/use-fetch?file=app.vue&terminal=dev) |
| `use-meta` | [GitHub](https://github.com/nuxt/framework/tree/main/examples/use-meta) | [Play Online](https://stackblitz.com/github/nuxt/framework/tree/main/examples/use-meta?file=app.vue&terminal=dev) |
| `use-head` | [GitHub](https://github.com/nuxt/framework/tree/main/examples/use-head) | [Play Online](https://stackblitz.com/github/nuxt/framework/tree/main/examples/use-head?file=app.vue&terminal=dev) |
| `use-state` | [GitHub](https://github.com/nuxt/framework/tree/main/examples/use-state) | [Play Online](https://stackblitz.com/github/nuxt/framework/tree/main/examples/use-state?file=app.vue&terminal=dev) |
| `components` | [GitHub](https://github.com/nuxt/framework/tree/main/examples/components) | [Play Online](https://stackblitz.com/github/nuxt/framework/tree/main/examples/components?file=app.vue&terminal=dev) |
| `composables` | [GitHub](https://github.com/nuxt/framework/tree/main/examples/composables) | [Play Online](https://stackblitz.com/github/nuxt/framework/tree/main/examples/composables?file=app.vue&terminal=dev) |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<NuxtExampleLayout example="composables/use-meta">
<NuxtExampleLayout example="composables/use-head">
<div
class="bg-gray-400/10 border-2 border-dashed border-gray-400/50 rounded-xl py-8 px-2 op-80"
>
Expand All @@ -26,7 +26,7 @@
<script>
export default {
setup () {
useMeta({
useHead({
bodyAttrs: {
class: 'test'
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "example-use-meta",
"name": "example-use-head",
"private": true,
"scripts": {
"build": "nuxi build",
Expand Down
File renamed without changes.
10 changes: 5 additions & 5 deletions packages/bridge/src/meta.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { resolve } from 'pathe'
import { addTemplate, useNuxt, installModule } from '@nuxt/kit'
import metaModule from '../../nuxt3/src/meta/module'
import metaModule from '../../nuxt3/src/head/module'
import { distDir } from './dirs'

const checkDocsMsg = 'Please see https://v3.nuxtjs.org for more information.'
Expand All @@ -16,18 +16,18 @@ export const setupMeta = async (opts: SetupMetaOptions) => {
if (opts.needsExplicitEnable) {
const metaPath = addTemplate({
filename: 'meta.mjs',
getContents: () => `export const useMeta = () => console.warn('${msgPrefix} To use \`useMeta\`, please set \`bridge.meta\` to \`true\` in your \`nuxt.config\`. ${checkDocsMsg}')`
getContents: () => `export const useHead = () => console.warn('${msgPrefix} To use \`useHead\`, please set \`bridge.meta\` to \`true\` in your \`nuxt.config\`. ${checkDocsMsg}')`
})
nuxt.options.alias['#meta'] = metaPath.dst
nuxt.options.alias['#head'] = metaPath.dst
return
}

if (nuxt.options.head && typeof nuxt.options.head === 'function') {
throw new TypeError(`${msgPrefix} The head() function in \`nuxt.config\` has been deprecated and in Nuxt 3 will need to be moved to \`app.vue\`. ${checkDocsMsg}`)
}

const runtimeDir = resolve(distDir, 'runtime/meta')
nuxt.options.alias['#meta'] = runtimeDir
const runtimeDir = resolve(distDir, 'runtime/head')
nuxt.options.alias['#head'] = runtimeDir

await installModule(metaModule)
}
1 change: 1 addition & 0 deletions packages/bridge/src/runtime/head
1 change: 0 additions & 1 deletion packages/bridge/src/runtime/meta

This file was deleted.

2 changes: 1 addition & 1 deletion packages/nuxt3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"imports": {
"#app": "./dist/app/index.mjs",
"#meta": "./dist/meta/runtime/index.mjs",
"#head": "./dist/head/runtime/index.mjs",
"#pages": "./dist/pages/runtime/index.mjs"
},
"files": [
Expand Down
4 changes: 2 additions & 2 deletions packages/nuxt3/src/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export * from './components'
// eslint-disable-next-line import/no-restricted-paths
export type { PageMeta } from '../pages/runtime'
// eslint-disable-next-line import/no-restricted-paths
export type { MetaObject } from '../meta/runtime'
export { useMeta } from '#meta'
export type { MetaObject } from '../head/runtime'
export { useHead, useMeta } from '#head'

export const isVue2 = false
export const isVue3 = true
5 changes: 3 additions & 2 deletions packages/nuxt3/src/auto-imports/presets.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { defineUnimportPreset, Preset } from 'unimport'

export const commonPresets: Preset[] = [
// #meta
// #head
defineUnimportPreset({
from: '#meta',
from: '#head',
imports: [
'useHead',
'useMeta'
]
}),
Expand Down
2 changes: 1 addition & 1 deletion packages/nuxt3/src/core/nuxt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { loadNuxtConfig, LoadNuxtOptions, nuxtCtx, installModule, addComponent,
// Temporary until finding better placement
/* eslint-disable import/no-restricted-paths */
import pagesModule from '../pages/module'
import metaModule from '../meta/module'
import metaModule from '../head/module'
import componentsModule from '../components/module'
import autoImportsModule from '../auto-imports/module'
/* eslint-enable */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ export default defineNuxtModule({
viewport: 'width=device-width, initial-scale=1'
},
setup (options, nuxt) {
const runtimeDir = nuxt.options.alias['#meta'] || resolve(distDir, 'meta/runtime')
const runtimeDir = nuxt.options.alias['#head'] || resolve(distDir, 'head/runtime')

// Transpile @nuxt/meta and @vueuse/head
nuxt.options.build.transpile.push('@vueuse/head')

// Add #meta alias
nuxt.options.alias['#meta'] = runtimeDir
// Add #head alias
nuxt.options.alias['#head'] = runtimeDir

// Global meta
const globalMeta: MetaObject = defu(nuxt.options.meta, {
const globalMeta: MetaObject = defu(nuxt.options.app.head, {
meta: [
{ charset: options.charset },
{ name: 'viewport', content: options.viewport }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { defineComponent } from 'vue'
import type { SetupContext } from 'vue'
import { useMeta } from './composables'
import { useHead } from './composables'

type Props = Readonly<Record<string, any>>

const removeUndefinedProps = (props: Props) =>
Object.fromEntries(Object.entries(props).filter(([, value]) => value !== undefined))

const setupForUseMeta = (metaFactory: (props: Props, ctx: SetupContext) => Record<string, any>, renderChild?: boolean) => (props: Props, ctx: SetupContext) => {
useMeta(() => metaFactory({ ...removeUndefinedProps(props), ...ctx.attrs }, ctx))
useHead(() => metaFactory({ ...removeUndefinedProps(props), ...ctx.attrs }, ctx))
return () => renderChild ? ctx.slots.default?.() : null
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,21 @@ import { useNuxtApp } from '#app'
* Alternatively, for reactive meta state, you can pass in a function
* that returns a meta object.
*/
export function useMeta (meta: MetaObject | ComputedGetter<MetaObject>) {
export function useHead (meta: MetaObject | ComputedGetter<MetaObject>) {
const resolvedMeta = isFunction(meta) ? computed(meta) : meta
useNuxtApp()._useMeta(resolvedMeta)
useNuxtApp()._useHead(resolvedMeta)
}

const _warned = {}
const warnOnce = (id: string, message: string) => {
if (!_warned[id]) {
console.warn(message)
_warned[id] = true
}
}
// TODO: remove useMeta support when Nuxt 3 is stable
/** @deprecated */
export function useMeta (meta: MetaObject | ComputedGetter<MetaObject>) {
warnOnce('useMeta', '[meta] useMeta has been renamed to useHead.')
return useHead(meta)
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default defineNuxtPlugin((nuxtApp) => {

nuxtApp.vueApp.use(manager)

nuxtApp._useMeta = (meta: MetaObject) => manager.addMeta(meta)
nuxtApp._useHead = (meta: MetaObject) => manager.addMeta(meta)

if (process.client) {
const teleportTarget = document.createElement('div')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default defineNuxtPlugin((nuxtApp) => {
headReady = true
})

nuxtApp._useMeta = (meta: MetaObject) => {
nuxtApp._useHead = (meta: MetaObject) => {
const headObj = ref(meta as any)
head.addHeadObjs(headObj)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { computed, getCurrentInstance } from 'vue'
import * as Components from './components'
import { useMeta } from './composables'
import { useHead } from './composables'
import { defineNuxtPlugin, useNuxtApp } from '#app'
// @ts-ignore
import metaConfig from '#build/meta.config.mjs'
Expand All @@ -23,12 +23,12 @@ const metaMixin = {
? computed(() => options.head(nuxtApp))
: options.head

useMeta(source)
useHead(source)
}
}

export default defineNuxtPlugin((nuxtApp) => {
useMeta(metaConfig.globalMeta)
useHead(metaConfig.globalMeta)

nuxtApp.vueApp.mixin(metaMixin)

Expand Down
Loading

0 comments on commit e90b8c2

Please sign in to comment.