docs: standardize indentation and tag positioning (#22157)

This commit is contained in:
Mahdi Shah Abbasian 2023-07-18 14:01:45 +03:30 committed by GitHub
parent 646137a63a
commit bea6ed1d9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 257 additions and 252 deletions

View File

@ -81,7 +81,7 @@ NUXT_API_SECRET=api_secret_token
These variables are exposed to the rest of your application using the [`useRuntimeConfig`](/docs/api/composables/use-runtime-config) composable. These variables are exposed to the rest of your application using the [`useRuntimeConfig`](/docs/api/composables/use-runtime-config) composable.
```vue [pages/index.vue] ```vue [pages/index.vue]
<script setup> <script setup lang="ts">
const runtimeConfig = useRuntimeConfig() const runtimeConfig = useRuntimeConfig()
</script> </script>
``` ```
@ -109,7 +109,7 @@ export default defineAppConfig({
These variables are exposed to the rest of your application using the [`useAppConfig`](/docs/api/composables/use-app-config) composable. These variables are exposed to the rest of your application using the [`useAppConfig`](/docs/api/composables/use-app-config) composable.
```vue [pages/index.vue] ```vue [pages/index.vue]
<script setup> <script setup lang="ts">
const appConfig = useAppConfig() const appConfig = useAppConfig()
</script> </script>
``` ```

View File

@ -255,7 +255,7 @@ You can leverage Vue SFC features to style your components with class and style
::code-group ::code-group
```vue [Ref and Reactive] ```vue [Ref and Reactive]
<script setup> <script setup lang="ts">
const isActive = ref(true) const isActive = ref(true)
const hasError = ref(false) const hasError = ref(false)
const classObject = reactive({ const classObject = reactive({
@ -263,12 +263,15 @@ const classObject = reactive({
'text-danger': false 'text-danger': false
}) })
</script> </script>
<div class="static" :class="{ active: isActive, 'text-danger': hasError }"></div>
<div :class="classObject"></div> <template>
<div class="static" :class="{ active: isActive, 'text-danger': hasError }"></div>
<div :class="classObject"></div>
</template>
``` ```
```vue [Computed] ```vue [Computed]
<script setup> <script setup lang="ts">
const isActive = ref(true) const isActive = ref(true)
const error = ref(null) const error = ref(null)
@ -277,13 +280,14 @@ const classObject = computed(() => ({
'text-danger': error.value && error.value.type === 'fatal' 'text-danger': error.value && error.value.type === 'fatal'
})) }))
</script> </script>
<template> <template>
<div :class="classObject"></div> <div :class="classObject"></div>
</template> </template>
``` ```
```vue [Array] ```vue [Array]
<script setup> <script setup lang="ts">
const isActive = ref(true) const isActive = ref(true)
const errorClass = ref('text-danger') const errorClass = ref('text-danger')
</script> </script>
@ -294,7 +298,7 @@ const errorClass = ref('text-danger')
``` ```
```vue [Style] ```vue [Style]
<script setup> <script setup lang="ts">
const activeColor = ref('red') const activeColor = ref('red')
const fontSize = ref(30) const fontSize = ref(30)
const styleObject = reactive({ color: 'red', fontSize: '13px' }) const styleObject = reactive({ color: 'red', fontSize: '13px' })
@ -317,7 +321,7 @@ You can reference JavaScript variable and expression within your style blocks wi
The binding will be dynamic, meaning that if the variable value changes, the style will be updated. The binding will be dynamic, meaning that if the variable value changes, the style will be updated.
```vue ```vue
<script setup> <script setup lang="ts">
const color = ref("red") const color = ref("red")
</script> </script>

View File

@ -72,7 +72,7 @@ When a `<NuxtLink>` enters the viewport on the client side, Nuxt will automatica
The `useRoute()` composable can be used in a `<script setup>` block or a `setup()` method of a Vue component to access the current route details. The `useRoute()` composable can be used in a `<script setup>` block or a `setup()` method of a Vue component to access the current route details.
```vue [pages/posts/[id].vue] ```vue [pages/posts/[id].vue]
<script setup> <script setup lang="ts">
const route = useRoute() const route = useRoute()
// When accessing /posts/1, route.params.id will be 1 // When accessing /posts/1, route.params.id will be 1
@ -110,7 +110,7 @@ export default defineNuxtRouteMiddleware((to, from) => {
``` ```
```html [pages/dashboard.vue] ```html [pages/dashboard.vue]
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
middleware: 'auth' middleware: 'auth'
}) })
@ -134,7 +134,7 @@ The `validate` property accepts the `route` as an argument. You can return a boo
If you have a more complex use case, then you can use anonymous route middleware instead. If you have a more complex use case, then you can use anonymous route middleware instead.
```vue [pages/posts/[id].vue] ```vue [pages/posts/[id].vue]
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
validate: async (route) => { validate: async (route) => {
// Check if the id is made up of digits // Check if the id is made up of digits

View File

@ -89,7 +89,7 @@ Because these component names match native HTML elements, it is very important t
<!-- @case-police-ignore html --> <!-- @case-police-ignore html -->
```vue [app.vue] ```vue [app.vue]
<script setup> <script setup lang="ts">
const title = ref('Hello World') const title = ref('Hello World')
</script> </script>
@ -161,7 +161,7 @@ It's recommended to use getters (`() => value`) over computed (`computed(() => v
``` ```
```vue [Components] ```vue [Components]
<script setup> <script setup lang="ts">
const description = ref('My amazing site.') const description = ref('My amazing site.')
</script> </script>
@ -227,7 +227,7 @@ Within your [`pages/` directory](/docs/guide/directory-structure/pages), you can
For example, you can first set the current page title (this is extracted at build time via a macro, so it can't be set dynamically): For example, you can first set the current page title (this is extracted at build time via a macro, so it can't be set dynamically):
```vue{}[pages/some-page.vue] ```vue{}[pages/some-page.vue]
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
title: 'Some Page' title: 'Some Page'
}) })
@ -237,7 +237,7 @@ definePageMeta({
And then in your layout file, you might use the route's metadata you have previously set: And then in your layout file, you might use the route's metadata you have previously set:
```vue{}[layouts/default.vue] ```vue{}[layouts/default.vue]
<script setup> <script setup lang="ts">
const route = useRoute() const route = useRoute()
useHead({ useHead({
@ -255,7 +255,7 @@ useHead({
In the example below, `titleTemplate` is set either as a string with the `%s` placeholder or as a `function`, which allows greater flexibility in setting the page title dynamically for each route of your Nuxt app: In the example below, `titleTemplate` is set either as a string with the `%s` placeholder or as a `function`, which allows greater flexibility in setting the page title dynamically for each route of your Nuxt app:
```vue [app.vue] ```vue [app.vue]
<script setup> <script setup lang="ts">
useHead({ useHead({
// as a string, // as a string,
// where `%s` is replaced with the title // where `%s` is replaced with the title

View File

@ -46,7 +46,7 @@ These composables are auto-imported and can be used in `setup` functions or life
[`useFetch`](/docs/api/composables/use-fetch) is the most straightforward way to perform data fetching. It is a wrapper around the [`useAsyncData`](/docs/api/composables/use-async-data) composable and `$fetch` utility. [`useFetch`](/docs/api/composables/use-fetch) is the most straightforward way to perform data fetching. It is a wrapper around the [`useAsyncData`](/docs/api/composables/use-async-data) composable and `$fetch` utility.
```vue [app.vue] ```vue [app.vue]
<script setup> <script setup lang="ts">
const { data: count } = await useFetch('/api/count') const { data: count } = await useFetch('/api/count')
</script> </script>
@ -116,6 +116,12 @@ The first argument of [`useAsyncData`](/docs/api/composables/use-async-data) is
By default, data fetching composables will wait for the resolution of their asynchronous function before navigating to a new page by using Vues Suspense. This feature can be ignored on client-side navigation with the `lazy` option. In that case, you will have to manually handle loading state using the `pending` value. By default, data fetching composables will wait for the resolution of their asynchronous function before navigating to a new page by using Vues Suspense. This feature can be ignored on client-side navigation with the `lazy` option. In that case, you will have to manually handle loading state using the `pending` value.
```vue [app.vue] ```vue [app.vue]
<script setup lang="ts">
const { pending, data: posts } = useFetch('/api/posts', {
lazy: true
})
</script>
<template> <template>
<!-- you will need to handle a loading state --> <!-- you will need to handle a loading state -->
<div v-if="pending"> <div v-if="pending">
@ -127,11 +133,6 @@ By default, data fetching composables will wait for the resolution of their asyn
</div> </div>
</div> </div>
</template> </template>
<script setup>
const { pending, data: posts } = useFetch('/api/posts', {
lazy: true
})
</script>
``` ```
You can alternatively use [`useLazyFetch`](/docs/api/composables/use-lazy-fetch) and `useLazyAsyncData` as convenient methods to perform the same. You can alternatively use [`useLazyFetch`](/docs/api/composables/use-lazy-fetch) and `useLazyAsyncData` as convenient methods to perform the same.
@ -163,7 +164,7 @@ const { pending, data: posts } = useFetch('/api/comments', {
The `pick` option helps you to minimize the payload size stored in your HTML document by only selecting the fields that you want returned from the composables. The `pick` option helps you to minimize the payload size stored in your HTML document by only selecting the fields that you want returned from the composables.
```vue ```vue
<script setup> <script setup lang="ts">
/* only pick the fields used in your template */ /* only pick the fields used in your template */
const { data: mountain } = await useFetch('/api/mountains/everest', { pick: ['title', 'description'] }) const { data: mountain } = await useFetch('/api/mountains/everest', { pick: ['title', 'description'] })
</script> </script>
@ -202,15 +203,15 @@ To get the cached data by key, you can use [`useNuxtData`](/docs/api/composables
If you want to fetch or refresh data manually, use the `execute` or `refresh` function provided by the composables. (`execute` is an alias for `refresh` that works in exactly the same way but is more semantic for cases when `immediate: false`). If you want to fetch or refresh data manually, use the `execute` or `refresh` function provided by the composables. (`execute` is an alias for `refresh` that works in exactly the same way but is more semantic for cases when `immediate: false`).
```vue ```vue
<script setup> <script setup lang="ts">
const { data, error, execute, refresh } = await useFetch('/api/users') const { data, error, execute, refresh } = await useFetch('/api/users')
</script> </script>
<template> <template>
<div> <div>
<p>{{ data }}</p> <p>{{ data }}</p>
<button @click="refresh">Refresh data</button> <button @click="refresh">Refresh data</button>
</div> </div>
</template> </template>
``` ```
@ -242,7 +243,7 @@ We can use [`useRequestHeaders`](/docs/api/composables/use-request-headers) to a
The example below adds the request headers to an isomorphic `$fetch` call to ensure that the API endpoint has access to the same `cookie` header originally sent by the user. The example below adds the request headers to an isomorphic `$fetch` call to ensure that the API endpoint has access to the same `cookie` header originally sent by the user.
```vue ```vue
<script setup> <script setup lang="ts">
const headers = useRequestHeaders(['cookie']) const headers = useRequestHeaders(['cookie'])
const { data } = await useFetch('/api/me', { headers }) const { data } = await useFetch('/api/me', { headers })
</script> </script>

View File

@ -36,7 +36,7 @@ Instead use `const useX = () => useState('x')`
In this example, we use a component-local counter state. Any other component that uses `useState('counter')` shares the same reactive state. In this example, we use a component-local counter state. Any other component that uses `useState('counter')` shares the same reactive state.
```vue [app.vue] ```vue [app.vue]
<script setup> <script setup lang="ts">
const counter = useState('counter', () => Math.round(Math.random() * 1000)) const counter = useState('counter', () => Math.round(Math.random() * 1000))
</script> </script>
@ -108,7 +108,7 @@ export const useLocaleDate = (date: Ref<Date> | Date, locale = useLocale()) => {
``` ```
```vue [app.vue] ```vue [app.vue]
<script setup> <script setup lang="ts">
const locales = useLocales() const locales = useLocales()
const locale = useLocale() const locale = useLocale()
const date = useLocaleDate(new Date('2016-10-26')) const date = useLocaleDate(new Date('2016-10-26'))
@ -141,7 +141,7 @@ export const useColor = () => useState<string>('color', () => 'pink')
``` ```
```vue [app.vue] ```vue [app.vue]
<script setup> <script setup lang="ts">
const color = useColor() // Same as useState('color') const color = useColor() // Same as useState('color')
</script> </script>

View File

@ -74,17 +74,17 @@ If you are running on Node 16 and you set any cookies when rendering your error
### Example ### Example
```vue [error.vue] ```vue [error.vue]
<template> <script setup lang="ts">
<button @click="handleError">Clear errors</button>
</template>
<script setup>
const props = defineProps({ const props = defineProps({
error: Object error: Object
}) })
const handleError = () => clearError({ redirect: '/' }) const handleError = () => clearError({ redirect: '/' })
</script> </script>
<template>
<button @click="handleError">Clear errors</button>
</template>
``` ```
## Error Helper Methods ## Error Helper Methods
@ -112,7 +112,7 @@ If you throw an error created with `createError`:
### Example ### Example
```vue [pages/movies/[slug].vue] ```vue [pages/movies/[slug].vue]
<script setup> <script setup lang="ts">
const route = useRoute() const route = useRoute()
const { data } = await useFetch(`/api/movies/${route.params.slug}`) const { data } = await useFetch(`/api/movies/${route.params.slug}`)
if (!data.value) { if (!data.value) {

View File

@ -30,9 +30,9 @@ You can also auto-import functions exported from custom folders or third-party p
Nuxt auto-imports functions and composables to perform [data fetching](/docs/getting-started/data-fetching), get access to the [app context](/docs/api/composables/use-nuxt-app) and [runtime config](/docs/guide/going-further/runtime-config), manage [state](/docs/getting-started/state-management) or define components and plugins. Nuxt auto-imports functions and composables to perform [data fetching](/docs/getting-started/data-fetching), get access to the [app context](/docs/api/composables/use-nuxt-app) and [runtime config](/docs/guide/going-further/runtime-config), manage [state](/docs/getting-started/state-management) or define components and plugins.
```vue ```vue
<script setup> <script setup lang="ts">
/* useAsyncData() and $fetch() are auto-imported */ /* useAsyncData() and $fetch() are auto-imported */
const { data, refresh, pending } = await useAsyncData('/api/hello', () => $fetch('/api/hello')) const { data, refresh, pending } = await useAsyncData('/api/hello', () => $fetch('/api/hello'))
</script> </script>
``` ```
@ -41,10 +41,10 @@ Nuxt auto-imports functions and composables to perform [data fetching](/docs/get
Vue 3 exposes Reactivity APIs like `ref` or `computed`, as well as lifecycle hooks and helpers that are auto-imported by Nuxt. Vue 3 exposes Reactivity APIs like `ref` or `computed`, as well as lifecycle hooks and helpers that are auto-imported by Nuxt.
```vue ```vue
<script setup> <script setup lang="ts">
/* ref() and computed() are auto-imported */ /* ref() and computed() are auto-imported */
const count = ref(1) const count = ref(1)
const double = computed(() => count.value * 2) const double = computed(() => count.value * 2)
</script> </script>
``` ```
@ -103,11 +103,11 @@ Nuxt directly auto-imports files created in defined directories:
Nuxt exposes every auto-import with the `#imports` alias that can be used to make the import explicit if needed: Nuxt exposes every auto-import with the `#imports` alias that can be used to make the import explicit if needed:
```vue ```vue
<script setup> <script setup lang="ts">
import { ref, computed } from '#imports' import { ref, computed } from '#imports'
const count = ref(1) const count = ref(1)
const double = computed(() => count.value * 2) const double = computed(() => count.value * 2)
</script> </script>
``` ```

View File

@ -94,9 +94,9 @@ The [Composition API](https://vuejs.org/guide/extras/composition-api-faq.html) i
Used with the `setup` keyword in the `<script>` definition, here is the above component rewritten with Composition API and Nuxt 3s auto-imported Reactivity APIs: Used with the `setup` keyword in the `<script>` definition, here is the above component rewritten with Composition API and Nuxt 3s auto-imported Reactivity APIs:
```vue ```vue
<script setup> <script setup lang="ts">
const count = ref(0); const count = ref(0);
const increment = () => count.value++; const increment = () => count.value++;
</script> </script>
``` ```

View File

@ -103,13 +103,13 @@ If you want to use the Vue `<component :is="someComputedComponent">` syntax, the
For example: For example:
```vue ```vue
<script setup lang="ts">
const MyButton = resolveComponent('MyButton')
</script>
<template> <template>
<component :is="clickable ? MyButton : 'div'" /> <component :is="clickable ? MyButton : 'div'" />
</template> </template>
<script setup>
const MyButton = resolveComponent('MyButton')
</script>
``` ```
::alert{type=warning} ::alert{type=warning}
@ -150,14 +150,6 @@ To dynamically import a component (also known as lazy-loading a component) all y
This is particularly useful if the component is not always needed. By using the `Lazy` prefix you can delay loading the component code until the right moment, which can be helpful for optimizing your JavaScript bundle size. This is particularly useful if the component is not always needed. By using the `Lazy` prefix you can delay loading the component code until the right moment, which can be helpful for optimizing your JavaScript bundle size.
```html [pages/index.vue] ```html [pages/index.vue]
<template>
<div>
<h1>Mountains</h1>
<LazyMountainsList v-if="show" />
<button v-if="!show" @click="show = true">Show List</button>
</div>
</template>
<script> <script>
export default { export default {
data() { data() {
@ -167,6 +159,14 @@ export default {
} }
} }
</script> </script>
<template>
<div>
<h1>Mountains</h1>
<LazyMountainsList v-if="show" />
<button v-if="!show" @click="show = true">Show List</button>
</div>
</template>
``` ```
## Direct Imports ## Direct Imports
@ -174,6 +174,11 @@ export default {
You can also explicitly import components from `#components` if you want or need to bypass Nuxt's auto-importing functionality. You can also explicitly import components from `#components` if you want or need to bypass Nuxt's auto-importing functionality.
```html [pages/index.vue] ```html [pages/index.vue]
<script setup lang="ts">
import { NuxtLink, LazyMountainsList } from '#components'
const show = ref(false)
</script>
<template> <template>
<div> <div>
<h1>Mountains</h1> <h1>Mountains</h1>
@ -182,11 +187,6 @@ You can also explicitly import components from `#components` if you want or need
<NuxtLink to="/">Home</NuxtLink> <NuxtLink to="/">Home</NuxtLink>
</div> </div>
</template> </template>
<script setup>
import { NuxtLink, LazyMountainsList } from '#components'
const show = ref(false)
</script>
``` ```
## `<ClientOnly>` Component ## `<ClientOnly>` Component

View File

@ -35,15 +35,15 @@ export default function () {
**Usage:** You can now use auto imported composable in `.js`, `.ts` and `.vue` files **Usage:** You can now use auto imported composable in `.js`, `.ts` and `.vue` files
```vue [app.vue] ```vue [app.vue]
<script setup lang="ts">
const foo = useFoo()
</script>
<template> <template>
<div> <div>
{{ foo }} {{ foo }}
</div> </div>
</template> </template>
<script setup>
const foo = useFoo()
</script>
``` ```
::LinkExample{link="/docs/examples/features/auto-imports"} ::LinkExample{link="/docs/examples/features/auto-imports"}

View File

@ -53,16 +53,16 @@ If you use a `app.vue` you will also need to add `<NuxtLayout>`:
You can directly override the default layout like this: You can directly override the default layout like this:
```vue{}[app.vue] ```vue{}[app.vue]
<script setup lang="ts">
// You might choose this based on an API call or logged-in status
const layout = "custom";
</script>
<template> <template>
<NuxtLayout :name="layout"> <NuxtLayout :name="layout">
<NuxtPage /> <NuxtPage />
</NuxtLayout> </NuxtLayout>
</template> </template>
<script setup>
// You might choose this based on an API call or logged-in status
const layout = "custom";
</script>
``` ```
Alternatively, you can override the default layout per-page like this: Alternatively, you can override the default layout per-page like this:
@ -115,13 +115,7 @@ Learn more about [defining page meta](/docs/guide/directory-structure/pages#page
You can also use a ref or computed property for your layout. You can also use a ref or computed property for your layout.
```vue ```vue
<template> <script setup lang="ts">
<div>
<button @click="enableCustomLayout">Update layout</button>
</div>
</template>
<script setup>
function enableCustomLayout () { function enableCustomLayout () {
setPageLayout('custom') setPageLayout('custom')
} }
@ -129,6 +123,12 @@ definePageMeta({
layout: false, layout: false,
}); });
</script> </script>
<template>
<div>
<button @click="enableCustomLayout">Update layout</button>
</div>
</template>
``` ```
::LinkExample{link="/docs/examples/features/layouts"} ::LinkExample{link="/docs/examples/features/layouts"}
@ -141,6 +141,12 @@ If you are using the `~/pages` integration, you can take full control by setting
::code-group ::code-group
```vue [pages/index.vue] ```vue [pages/index.vue]
<script setup lang="ts">
definePageMeta({
layout: false,
});
</script>
<template> <template>
<div> <div>
<NuxtLayout name="custom"> <NuxtLayout name="custom">
@ -150,12 +156,6 @@ If you are using the `~/pages` integration, you can take full control by setting
</NuxtLayout> </NuxtLayout>
</div> </div>
</template> </template>
<script setup>
definePageMeta({
layout: false,
});
</script>
``` ```
```vue [layouts/custom.vue] ```vue [layouts/custom.vue]

View File

@ -80,7 +80,7 @@ middleware/
``` ```
```vue [pages/profile.vue] ```vue [pages/profile.vue]
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
middleware: [ middleware: [
function (to, from) { function (to, from) {
@ -160,7 +160,7 @@ export default defineNuxtPlugin(() => {
In your page file, you can reference this route middleware In your page file, you can reference this route middleware
```vue ```vue
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
middleware: ["auth"] middleware: ["auth"]
// or middleware: 'auth' // or middleware: 'auth'

View File

@ -125,7 +125,7 @@ Navigating to `/users-admins/123` would render:
If you want to access the route using Composition API, there is a global [`useRoute`](/docs/api/composables/use-route) function that will allow you to access the route just like `this.$route` in the Options API. If you want to access the route using Composition API, there is a global [`useRoute`](/docs/api/composables/use-route) function that will allow you to access the route just like `this.$route` in the Options API.
```vue ```vue
<script setup> <script setup lang="ts">
const route = useRoute() const route = useRoute()
if (route.params.group === 'admins' && !route.params.id) { if (route.params.group === 'admins' && !route.params.id) {
@ -209,7 +209,7 @@ If you want more control over when the `<NuxtPage>` component is re-rendered (fo
Or alternatively: Or alternatively:
```html{}[pages/child.vue] ```html{}[pages/child.vue]
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
key: route => route.fullPath key: route => route.fullPath
}) })
@ -224,7 +224,7 @@ definePageMeta({
You might want to define metadata for each route in your app. You can do this using the `definePageMeta` macro, which will work both in `<script>` and in `<script setup>`: You might want to define metadata for each route in your app. You can do this using the `definePageMeta` macro, which will work both in `<script>` and in `<script setup>`:
```vue ```vue
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
title: 'My home page' title: 'My home page'
}) })
@ -234,7 +234,7 @@ definePageMeta({
This data can then be accessed throughout the rest of your app from the `route.meta` object. This data can then be accessed throughout the rest of your app from the `route.meta` object.
```vue ```vue
<script setup> <script setup lang="ts">
const route = useRoute() const route = useRoute()
console.log(route.meta.title) // My home page console.log(route.meta.title) // My home page
@ -246,7 +246,7 @@ If you are using nested routes, the page metadata from all these routes will be
Much like `defineEmits` or `defineProps` (see [Vue docs](https://vuejs.org/api/sfc-script-setup.html#defineprops-defineemits)), `definePageMeta` is a **compiler macro**. It will be compiled away so you cannot reference it within your component. Instead, the metadata passed to it will be hoisted out of the component. Therefore, the page meta object cannot reference the component (or values defined on the component). However, it can reference imported bindings. Much like `defineEmits` or `defineProps` (see [Vue docs](https://vuejs.org/api/sfc-script-setup.html#defineprops-defineemits)), `definePageMeta` is a **compiler macro**. It will be compiled away so you cannot reference it within your component. Instead, the metadata passed to it will be hoisted out of the component. Therefore, the page meta object cannot reference the component (or values defined on the component). However, it can reference imported bindings.
```vue ```vue
<script setup> <script setup lang="ts">
import { someData } from '~/utils/example' import { someData } from '~/utils/example'
const title = ref('') const title = ref('')
@ -340,7 +340,7 @@ Nuxt 3 allows programmatic navigation through the `navigateTo()` utility method.
**Note:** Ensure to always `await` on `navigateTo` or chain its result by returning from functions. **Note:** Ensure to always `await` on `navigateTo` or chain its result by returning from functions.
```vue ```vue
<script setup> <script setup lang="ts">
const name = ref(''); const name = ref('');
const type = ref(1); const type = ref(1);

View File

@ -136,16 +136,16 @@ export default defineNuxtPlugin(() => {
In another file you can use this: In another file you can use this:
```vue ```vue
<script setup lang="ts">
// alternatively, you can also use it here
const { $hello } = useNuxtApp()
</script>
<template> <template>
<div> <div>
{{ $hello('world') }} {{ $hello('world') }}
</div> </div>
</template> </template>
<script setup lang="ts">
// alternatively, you can also use it here
const { $hello } = useNuxtApp()
</script>
``` ```
## Typing Plugins ## Typing Plugins

View File

@ -29,7 +29,7 @@ export default defineEventHandler((event) => {
You can now universally call this API in your pages and components: You can now universally call this API in your pages and components:
```vue [pages/index.vue] ```vue [pages/index.vue]
<script setup> <script setup lang="ts">
const { data } = await useFetch('/api/hello') const { data } = await useFetch('/api/hello')
</script> </script>
@ -424,13 +424,6 @@ export default defineEventHandler(async (event) => {
Create a new file in `app.vue`: Create a new file in `app.vue`:
```vue [app.vue] ```vue [app.vue]
<template>
<div>
<div>Post state: {{ resDataSuccess }}</div>
<div>Get Data: {{ resData.text }}</div>
</div>
</template>
<script setup lang="ts"> <script setup lang="ts">
const { data: resDataSuccess } = await useFetch('/api/test', { const { data: resDataSuccess } = await useFetch('/api/test', {
method: 'post', method: 'post',
@ -438,6 +431,13 @@ Create a new file in `app.vue`:
}) })
const { data: resData } = await useFetch('/api/test') const { data: resData } = await useFetch('/api/test')
</script> </script>
<template>
<div>
<div>Post state: {{ resDataSuccess }}</div>
<div>Get Data: {{ resData.text }}</div>
</div>
</template>
``` ```
::ReadMore{link="/docs/guide/directory-structure/server"} ::ReadMore{link="/docs/guide/directory-structure/server"}

View File

@ -91,19 +91,19 @@ Within the Vue part of your Nuxt app, you will need to call `useRuntimeConfig()`
The entire runtime config is available on the server-side, but it is read-only to avoid context sharing. The entire runtime config is available on the server-side, but it is read-only to avoid context sharing.
```vue ```vue
<template> <script setup lang="ts">
<div>
<div>Check developer console!</div>
</div>
</template>
<script setup>
const config = useRuntimeConfig() const config = useRuntimeConfig()
console.log('Runtime config:', config) console.log('Runtime config:', config)
if (process.server) { if (process.server) {
console.log('API secret:', config.apiSecret) console.log('API secret:', config.apiSecret)
} }
</script> </script>
<template>
<div>
<div>Check developer console!</div>
</div>
</template>
``` ```
**🛑 Security note:** Be careful not to expose runtime config keys to the client-side by either rendering them or passing them to `useState`. **🛑 Security note:** Be careful not to expose runtime config keys to the client-side by either rendering them or passing them to `useState`.

View File

@ -41,9 +41,9 @@ App hooks can be mainly used by [Nuxt Plugins](/docs/guide/directory-structure/p
```js [plugins/test.ts] ```js [plugins/test.ts]
export default defineNuxtPlugin((nuxtApp) => { export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('page:start', () => { nuxtApp.hook('page:start', () => {
/* your code goes here */ /* your code goes here */
}) })
}) })
``` ```

View File

@ -23,6 +23,11 @@ const cookie = useCookie(name, options)
The example below creates a cookie called `counter`. If the cookie doesn't exist, it is initially set to a random value. Whenever we update the `counter` variable, the cookie will be updated accordingly. The example below creates a cookie called `counter`. If the cookie doesn't exist, it is initially set to a random value. Whenever we update the `counter` variable, the cookie will be updated accordingly.
```vue ```vue
<script setup lang="ts">
const counter = useCookie('counter')
counter.value = counter.value || Math.round(Math.random() * 1000)
</script>
<template> <template>
<div> <div>
<h1>Counter: {{ counter || '-' }}</h1> <h1>Counter: {{ counter || '-' }}</h1>
@ -31,11 +36,6 @@ The example below creates a cookie called `counter`. If the cookie doesn't exist
<button @click="counter++">+</button> <button @click="counter++">+</button>
</div> </div>
</template> </template>
<script setup>
const counter = useCookie('counter')
counter.value = counter.value || Math.round(Math.random() * 1000)
</script>
``` ```
:button-link[Open on StackBlitz]{href="https://stackblitz.com/github/nuxt/examples/tree/main/advanced/use-cookie?terminal=dev&file=app.vue" blank} :button-link[Open on StackBlitz]{href="https://stackblitz.com/github/nuxt/examples/tree/main/advanced/use-cookie?terminal=dev&file=app.vue" blank}
@ -143,11 +143,7 @@ Specifies the `boolean` or `string` value for [watch](https://vuejs.org/api/reac
**Example 1:** **Example 1:**
```vue ```vue
<template> <script setup lang="ts">
<div>User score: {{ user?.score }}</div>
</template>
<script setup>
const user = useCookie( const user = useCookie(
'userInfo', 'userInfo',
{ {
@ -160,21 +156,16 @@ if (user.value && user.value !== null) {
user.value.score++; // userInfo cookie not update with this change user.value.score++; // userInfo cookie not update with this change
} }
</script> </script>
<template>
<div>User score: {{ user?.score }}</div>
</template>
``` ```
**Example 2:** **Example 2:**
```vue ```vue
<template> <script setup lang="ts">
<div>
<h1>List</h1>
<pre>{{ list }}</pre>
<button @click="add">Add</button>
<button @click="save">Save</button>
</div>
</template>
<script setup>
const list = useCookie( const list = useCookie(
'list', 'list',
{ {
@ -195,6 +186,15 @@ function save() {
} }
} }
</script> </script>
<template>
<div>
<h1>List</h1>
<pre>{{ list }}</pre>
<button @click="add">Add</button>
<button @click="save">Save</button>
</div>
</template>
``` ```
## Handling Cookies in API Routes ## Handling Cookies in API Routes

View File

@ -17,13 +17,7 @@ By default, [useAsyncData](/docs/api/composables/use-async-data) blocks navigati
## Example ## Example
```vue ```vue
<template> <script setup lang="ts">
<div>
{{ pending ? 'Loading' : count }}
</div>
</template>
<script setup>
/* Navigation will occur before fetching is complete. /* Navigation will occur before fetching is complete.
Handle pending and error states directly within your component's template Handle pending and error states directly within your component's template
*/ */
@ -34,6 +28,12 @@ watch(count, (newCount) => {
// to its contents immediately, but you can watch it. // to its contents immediately, but you can watch it.
}) })
</script> </script>
<template>
<div>
{{ pending ? 'Loading' : count }}
</div>
</template>
``` ```
::alert{type=warning} ::alert{type=warning}

View File

@ -17,6 +17,17 @@ By default, [useFetch](/docs/api/composables/use-fetch) blocks navigation until
## Example ## Example
```vue ```vue
<script setup lang="ts">
/* Navigation will occur before fetching is complete.
Handle pending and error states directly within your component's template
*/
const { pending, data: posts } = await useLazyFetch('/api/posts')
watch(posts, (newPosts) => {
// Because posts might start out null, you won't have access
// to its contents immediately, but you can watch it.
})
</script>
<template> <template>
<div v-if="pending"> <div v-if="pending">
Loading ... Loading ...
@ -27,17 +38,6 @@ By default, [useFetch](/docs/api/composables/use-fetch) blocks navigation until
</div> </div>
</div> </div>
</template> </template>
<script setup>
/* Navigation will occur before fetching is complete.
Handle pending and error states directly within your component's template
*/
const { pending, data: posts } = await useLazyFetch('/api/posts')
watch(posts, (newPosts) => {
// Because posts might start out null, you won't have access
// to its contents immediately, but you can watch it.
})
</script>
``` ```
::alert{type=warning} ::alert{type=warning}

View File

@ -5,8 +5,8 @@
You can use `useNuxtApp()` within composables, plugins and components. You can use `useNuxtApp()` within composables, plugins and components.
```vue [app.vue] ```vue [app.vue]
<script setup> <script setup lang="ts">
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
</script> </script>
``` ```
@ -90,7 +90,7 @@ await nuxtApp.callHook('my-plugin:init')
- **data** (object) - When you fetch the data from an API endpoint using either [`useFetch`](/docs/api/composables/use-fetch) or [`useAsyncData`](/docs/api/composables/use-async-data) , resulting payload can be accessed from the `payload.data`. This data is cached and helps you prevent fetching the same data in case an identical request is made more than once. - **data** (object) - When you fetch the data from an API endpoint using either [`useFetch`](/docs/api/composables/use-fetch) or [`useAsyncData`](/docs/api/composables/use-async-data) , resulting payload can be accessed from the `payload.data`. This data is cached and helps you prevent fetching the same data in case an identical request is made more than once.
```vue [app.vue] ```vue [app.vue]
<script setup> <script setup lang="ts">
const { data } = await useAsyncData('count', () => $fetch('/api/count')) const { data } = await useAsyncData('count', () => $fetch('/api/count'))
</script> </script>
``` ```

View File

@ -26,7 +26,7 @@ We can use [`useRequestHeaders`](/docs/api/composables/use-request-headers) to a
The example below adds the `authorization` request header to an isomorphic `$fetch` call. The example below adds the `authorization` request header to an isomorphic `$fetch` call.
```vue [pages/some-page.vue] ```vue [pages/some-page.vue]
<script setup> <script setup lang="ts">
const { data } = await useFetch('/api/confidential', { const { data } = await useFetch('/api/confidential', {
headers: useRequestHeaders(['authorization']) headers: useRequestHeaders(['authorization'])
}) })

View File

@ -5,7 +5,7 @@
::code-group ::code-group
```vue [pages/about.vue] ```vue [pages/about.vue]
<script setup> <script setup lang="ts">
const url = useRequestURL() const url = useRequestURL()
</script> </script>

View File

@ -14,7 +14,7 @@ Within the template of a Vue component, you can access the route using `$route`.
In the following example, we call an API via [`useFetch`](/docs/api/composables/use-fetch) using a dynamic page parameter - `slug` - as part of the URL. In the following example, we call an API via [`useFetch`](/docs/api/composables/use-fetch) using a dynamic page parameter - `slug` - as part of the URL.
```html [~/pages/[slug].vue] ```html [~/pages/[slug].vue]
<script setup> <script setup lang="ts">
const route = useRoute() const route = useRoute()
const { data: mountain } = await useFetch(`https://api.nuxtjs.dev/mountains/${route.params.slug}`) const { data: mountain } = await useFetch(`https://api.nuxtjs.dev/mountains/${route.params.slug}`)
</script> </script>

View File

@ -37,7 +37,7 @@ For example, passing `static` key, `NuxtPage` component is rendered only once wh
Alternatively, `pageKey` can be passed as a `key` value via `definePageMeta` from the `<script>` section of your Vue component in the `/pages` directory. Alternatively, `pageKey` can be passed as a `key` value via `definePageMeta` from the `<script>` section of your Vue component in the `/pages` directory.
```js ```js
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
key: route => route.fullPath key: route => route.fullPath
}) })
@ -51,16 +51,16 @@ definePageMeta({
To get the ref of a page component, access it through `ref.value.pageRef` To get the ref of a page component, access it through `ref.value.pageRef`
````html ````html
<template>
<NuxtPage ref="page" />
</template>
<script setup lang="ts"> <script setup lang="ts">
const page = ref() const page = ref()
function logFoo () { function logFoo () {
page.value.pageRef.foo() page.value.pageRef.foo()
} }
</script> </script>
<template>
<NuxtPage ref="page" />
</template>
```` ````
## Custom Props ## Custom Props

View File

@ -23,16 +23,16 @@ You can use `<NuxtLayout />` component to activate `default` layout on `app.vue`
### Examples ### Examples
```vue [pages/index.vue] ```vue [pages/index.vue]
<script setup lang="ts">
// layouts/custom.vue
const layout = 'custom'
</script>
<template> <template>
<NuxtLayout :name="layout"> <NuxtLayout :name="layout">
<NuxtPage /> <NuxtPage />
</NuxtLayout> </NuxtLayout>
</template> </template>
<script setup>
// layouts/custom.vue
const layout = 'custom'
</script>
``` ```
::alert{icon=👉} ::alert{icon=👉}
@ -66,16 +66,16 @@ Please note the layout name is normalized to kebab-case, so if your layout file
To get the ref of a layout component, access it through `ref.value.layoutRef` To get the ref of a layout component, access it through `ref.value.layoutRef`
````html ````html
<template>
<NuxtLayout ref="layout" />
</template>
<script setup lang="ts"> <script setup lang="ts">
const layout = ref() const layout = ref()
function logFoo () { function logFoo () {
layout.value.layoutRef.foo() layout.value.layoutRef.foo()
} }
</script> </script>
<template>
<NuxtLayout ref="layout" />
</template>
```` ````
::ReadMore{link="/docs/guide/directory-structure/layouts"} ::ReadMore{link="/docs/guide/directory-structure/layouts"}

View File

@ -14,7 +14,7 @@ However, using `$fetch` in components without wrapping it with [`useAsyncData`](
We recommend to use [`useFetch`](https://nuxt.com/docs/api/composables/use-fetch) or [`useAsyncData`](https://nuxt.com/docs/api/composables/use-async-data) + `$fetch` to prevent double data fetching when fetching the component data. We recommend to use [`useFetch`](https://nuxt.com/docs/api/composables/use-fetch) or [`useAsyncData`](https://nuxt.com/docs/api/composables/use-async-data) + `$fetch` to prevent double data fetching when fetching the component data.
```vue ```vue
<script setup> <script setup lang="ts">
// During SSR data is fetched twice, once on the server and once on the client. // During SSR data is fetched twice, once on the server and once on the client.
const dataTwice = await $fetch('/api/item') const dataTwice = await $fetch('/api/item')
@ -31,7 +31,7 @@ const { data } = await useFetch('/api/item')
You can use `$fetch` for any method that are executed only on client-side. You can use `$fetch` for any method that are executed only on client-side.
```vue ```vue
<script setup> <script setup lang="ts">
function contactForm() { function contactForm() {
$fetch('/api/contact', { $fetch('/api/contact', {
method: 'POST', method: 'POST',

View File

@ -20,7 +20,7 @@ If you throw an error created with `createError`:
### Example ### Example
```vue [pages/movies/[slug].vue] ```vue [pages/movies/[slug].vue]
<script setup> <script setup lang="ts">
const route = useRoute() const route = useRoute()
const { data } = await useFetch(`/api/movies/${route.params.slug}`) const { data } = await useFetch(`/api/movies/${route.params.slug}`)
if (!data.value) { if (!data.value) {

View File

@ -7,10 +7,10 @@ title: "definePageMeta"
`definePageMeta` is a compiler macro that you can use to set metadata for your **page** components located in the [`pages/` directory](/docs/guide/directory-structure/pages) (unless [set otherwise](/docs/api/configuration/nuxt-config#pages)). This way you can set custom metadata for each static or dynamic route of your Nuxt application. `definePageMeta` is a compiler macro that you can use to set metadata for your **page** components located in the [`pages/` directory](/docs/guide/directory-structure/pages) (unless [set otherwise](/docs/api/configuration/nuxt-config#pages)). This way you can set custom metadata for each static or dynamic route of your Nuxt application.
```vue [pages/some-page.vue] ```vue [pages/some-page.vue]
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
layout: 'default' layout: 'default'
}) })
</script> </script>
``` ```
@ -115,16 +115,16 @@ The example below demonstrates:
- adding `pageType` as a custom property: - adding `pageType` as a custom property:
```vue [pages/some-page.vue] ```vue [pages/some-page.vue]
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
key: (route) => route.fullPath, key: (route) => route.fullPath,
keepalive: { keepalive: {
exclude: ['modal'] exclude: ['modal']
}, },
pageType: 'Checkout' pageType: 'Checkout'
}) })
</script> </script>
``` ```
@ -133,28 +133,28 @@ The example below demonstrates:
The example below shows how the middleware can be defined using a `function` directly within the `definePageMeta` or set as a `string` that matches the middleware file name located in the `middleware/` directory: The example below shows how the middleware can be defined using a `function` directly within the `definePageMeta` or set as a `string` that matches the middleware file name located in the `middleware/` directory:
```vue [pages/some-page.vue] ```vue [pages/some-page.vue]
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
// define middleware as a function // define middleware as a function
middleware: [ middleware: [
function (to, from) { function (to, from) {
const auth = useState('auth') const auth = useState('auth')
if (!auth.value.authenticated) { if (!auth.value.authenticated) {
return navigateTo('/login') return navigateTo('/login')
}
if (to.path !== '/checkout') {
return navigateTo('/checkout')
}
} }
],
// ... or a string if (to.path !== '/checkout') {
middleware: 'auth' return navigateTo('/checkout')
}
}
],
// ... or multiple strings // ... or a string
middleware: ['auth', 'another-named-middleware'] middleware: 'auth'
// ... or multiple strings
middleware: ['auth', 'another-named-middleware']
}) })
</script> </script>
``` ```
@ -164,13 +164,13 @@ The example below shows how the middleware can be defined using a `function` dir
You can define the layout that matches the layout's file name located (by default) in the [`layouts/` directory](/docs/guide/directory-structure/layouts). You can also disable the layout by setting the `layout` to `false`: You can define the layout that matches the layout's file name located (by default) in the [`layouts/` directory](/docs/guide/directory-structure/layouts). You can also disable the layout by setting the `layout` to `false`:
```vue [pages/some-page.vue] ```vue [pages/some-page.vue]
<script setup> <script setup lang="ts">
definePageMeta({ definePageMeta({
// set custom layout // set custom layout
layout: 'admin' layout: 'admin'
// ... or disable a default layout // ... or disable a default layout
layout: false layout: false
}) })
</script> </script>
``` ```

View File

@ -127,7 +127,7 @@ An object accepting the following properties:
### Navigating Within a Vue Component ### Navigating Within a Vue Component
```vue ```vue
<script setup> <script setup lang="ts">
// passing 'to' as a string // passing 'to' as a string
await navigateTo('/search') await navigateTo('/search')
@ -162,7 +162,7 @@ export default defineNuxtRouteMiddleware((to, from) => {
### Navigating to an External URL ### Navigating to an External URL
```vue ```vue
<script setup> <script setup lang="ts">
// will throw an error; // will throw an error;
// navigating to an external URL is not allowed by default // navigating to an external URL is not allowed by default
await navigateTo('https://nuxt.com') await navigateTo('https://nuxt.com')
@ -177,7 +177,7 @@ await navigateTo('https://nuxt.com', {
### Navigating using open() ### Navigating using open()
```vue ```vue
<script setup> <script setup lang="ts">
// will open 'https://nuxt.com' in a new tab // will open 'https://nuxt.com' in a new tab
await navigateTo('https://nuxt.com', { await navigateTo('https://nuxt.com', {
open: { open: {

View File

@ -28,15 +28,7 @@ refreshNuxtData(keys?: string | string[])
This example below refreshes all data being fetched using [`useAsyncData`](/docs/api/composables/use-async-data) and [`useFetch`](/docs/api/composables/use-fetch) on the current page. This example below refreshes all data being fetched using [`useAsyncData`](/docs/api/composables/use-async-data) and [`useFetch`](/docs/api/composables/use-fetch) on the current page.
```vue [pages/some-page.vue] ```vue [pages/some-page.vue]
<template> <script setup lang="ts">
<div>
<button :disabled="refreshing" @click="refreshAll">
Refetch All Data
</button>
</div>
</template>
<script setup>
const refreshing = ref(false) const refreshing = ref(false)
const refreshAll = async () => { const refreshAll = async () => {
refreshing.value = true refreshing.value = true
@ -47,6 +39,14 @@ const refreshAll = async () => {
} }
} }
</script> </script>
<template>
<div>
<button :disabled="refreshing" @click="refreshAll">
Refetch All Data
</button>
</div>
</template>
``` ```
### Refresh Specific Data ### Refresh Specific Data
@ -54,17 +54,17 @@ const refreshAll = async () => {
This example below refreshes only data where the key matches to `count`. This example below refreshes only data where the key matches to `count`.
```vue [pages/some-page.vue] ```vue [pages/some-page.vue]
<script setup lang="ts">
const { pending, data: count } = await useLazyAsyncData('count', () => $fetch('/api/count'))
const refresh = () => refreshNuxtData('count')
</script>
<template> <template>
<div> <div>
{{ pending ? 'Loading' : count }} {{ pending ? 'Loading' : count }}
</div> </div>
<button @click="refresh">Refresh</button> <button @click="refresh">Refresh</button>
</template> </template>
<script setup>
const { pending, data: count } = await useLazyAsyncData('count', () => $fetch('/api/count'))
const refresh = () => refreshNuxtData('count')
</script>
``` ```
::ReadMore{link="/docs/getting-started/data-fetching"} ::ReadMore{link="/docs/getting-started/data-fetching"}

View File

@ -260,7 +260,7 @@ Nuxt Bridge does not support `definePageMeta`.
Nuxt Bridge provides a new Nuxt 3 meta API that can be accessed with a new [`useHead`](/docs/api/composables/use-head) composable. Nuxt Bridge provides a new Nuxt 3 meta API that can be accessed with a new [`useHead`](/docs/api/composables/use-head) composable.
```vue ```vue
<script setup> <script setup lang="ts">
useHead({ useHead({
title: 'My Nuxt App', title: 'My Nuxt App',
}) })

View File

@ -46,7 +46,7 @@ export default {
``` ```
```vue [Nuxt 3] ```vue [Nuxt 3]
<script setup> <script setup lang="ts">
const title = ref('My App') const title = ref('My App')
const description = ref('My App Description') const description = ref('My App Description')

View File

@ -160,7 +160,7 @@ export default {
</div> </div>
</template> </template>
<script setup> <script setup lang="ts">
// This compiler macro works in both <script> and <script setup> // This compiler macro works in both <script> and <script setup>
definePageMeta({ definePageMeta({
// you can also pass a string or a computed property // you can also pass a string or a computed property
@ -210,7 +210,7 @@ export default {
``` ```
```vue [Nuxt 3] ```vue [Nuxt 3]
<script setup> <script setup lang="ts">
const router = useRouter(); const router = useRouter();
function navigate(){ function navigate(){

View File

@ -43,11 +43,11 @@ Within your methods and templates, you could use the `post` variable similar how
With Nuxt 3, you can perform this data fetching using composables in your `setup()` method or `<script setup>` tag: With Nuxt 3, you can perform this data fetching using composables in your `setup()` method or `<script setup>` tag:
```vue ```vue
<script setup> <script setup lang="ts">
// Define params wherever, through `defineProps()`, `useRoute()`, etc. // Define params wherever, through `defineProps()`, `useRoute()`, etc.
const { data: post, refresh } = await useAsyncData('post', () => $fetch(`https://api.nuxtjs.dev/posts/${params.id}`) ) const { data: post, refresh } = await useAsyncData('post', () => $fetch(`https://api.nuxtjs.dev/posts/${params.id}`) )
// Or instead - useFetch is a convenience wrapper around useAsyncData when you're just performing a simple fetch // Or instead - useFetch is a convenience wrapper around useAsyncData when you're just performing a simple fetch
const { data: post, refresh } = await useFetch(`https://api.nuxtjs.dev/posts/${params.id}`) const { data: post, refresh } = await useFetch(`https://api.nuxtjs.dev/posts/${params.id}`)
</script> </script>
``` ```
@ -136,7 +136,7 @@ The validate hook in Nuxt 3 only accepts a single argument, the `route`. Just as
This is not supported in Nuxt 3. Instead, you can directly use a watcher to trigger refetching data. This is not supported in Nuxt 3. Instead, you can directly use a watcher to trigger refetching data.
```vue [pages/users/[id].vue] ```vue [pages/users/[id].vue]
<script setup> <script setup lang="ts">
const route = useRoute() const route = useRoute()
const { data, refresh } = await useFetch('/api/user') const { data, refresh } = await useFetch('/api/user')
watch(() => route.query, () => refresh()) watch(() => route.query, () => refresh())

View File

@ -31,11 +31,11 @@ export default defineNuxtConfig({
``` ```
```vue [pages/index.vue] ```vue [pages/index.vue]
<script setup> <script setup lang="ts">
const config = useRuntimeConfig() const config = useRuntimeConfig()
// instead of process.env you will now access config.public.apiBase // instead of process.env you will now access config.public.apiBase
console.log(config.public.apiBase) console.log(config.public.apiBase)
</script> </script>
``` ```