@nuxt/docs 4.0.3 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/1.getting-started/01.introduction.md +1 -1
- package/1.getting-started/03.configuration.md +2 -2
- package/1.getting-started/04.views.md +15 -15
- package/1.getting-started/05.assets.md +6 -6
- package/1.getting-started/06.styling.md +8 -8
- package/1.getting-started/07.routing.md +7 -7
- package/1.getting-started/08.seo-meta.md +9 -9
- package/1.getting-started/09.transitions.md +15 -15
- package/1.getting-started/10.data-fetching.md +9 -9
- package/1.getting-started/11.state-management.md +9 -9
- package/1.getting-started/12.error-handling.md +1 -1
- package/1.getting-started/14.layers.md +23 -2
- package/1.getting-started/15.prerendering.md +2 -2
- package/1.getting-started/17.testing.md +72 -19
- package/1.getting-started/18.upgrade.md +7 -7
- package/2.guide/1.concepts/1.auto-imports.md +6 -6
- package/2.guide/1.concepts/10.nuxt-lifecycle.md +6 -6
- package/2.guide/1.concepts/2.vuejs-development.md +3 -3
- package/2.guide/1.concepts/3.rendering.md +2 -2
- package/2.guide/1.concepts/8.typescript.md +1 -1
- package/2.guide/2.directory-structure/1.app/1.components.md +18 -18
- package/2.guide/2.directory-structure/1.app/1.composables.md +11 -11
- package/2.guide/2.directory-structure/1.app/1.layouts.md +7 -7
- package/2.guide/2.directory-structure/1.app/1.middleware.md +41 -3
- package/2.guide/2.directory-structure/1.app/1.pages.md +16 -16
- package/2.guide/2.directory-structure/1.app/1.plugins.md +7 -7
- package/2.guide/2.directory-structure/1.app/1.utils.md +3 -3
- package/2.guide/2.directory-structure/1.app/3.app-config.md +2 -2
- package/2.guide/2.directory-structure/1.app/3.app.md +12 -12
- package/2.guide/2.directory-structure/1.content.md +2 -2
- package/2.guide/2.directory-structure/1.public.md +1 -1
- package/2.guide/2.directory-structure/1.server.md +3 -3
- package/2.guide/2.directory-structure/1.shared.md +3 -3
- package/2.guide/2.directory-structure/2.nuxtrc.md +4 -0
- package/2.guide/3.going-further/1.experimental-features.md +38 -5
- package/2.guide/3.going-further/10.runtime-config.md +2 -2
- package/2.guide/3.going-further/2.hooks.md +1 -1
- package/2.guide/3.going-further/3.modules.md +50 -1
- package/2.guide/3.going-further/6.nuxt-app.md +2 -2
- package/2.guide/3.going-further/7.layers.md +34 -10
- package/2.guide/3.going-further/9.debugging.md +2 -1
- package/2.guide/4.recipes/1.custom-routing.md +1 -1
- package/2.guide/4.recipes/2.vite-plugin.md +1 -1
- package/2.guide/4.recipes/3.custom-usefetch.md +4 -4
- package/2.guide/4.recipes/4.sessions-and-authentication.md +4 -4
- package/2.guide/5.best-practices/performance.md +2 -2
- package/3.api/1.components/1.client-only.md +2 -2
- package/3.api/1.components/1.dev-only.md +1 -1
- package/3.api/1.components/1.nuxt-client-fallback.md +1 -1
- package/3.api/1.components/12.nuxt-route-announcer.md +2 -2
- package/3.api/1.components/2.nuxt-page.md +8 -8
- package/3.api/1.components/3.nuxt-layout.md +13 -13
- package/3.api/1.components/4.nuxt-link.md +9 -9
- package/3.api/1.components/5.nuxt-loading-indicator.md +2 -2
- package/3.api/1.components/7.nuxt-welcome.md +1 -1
- package/3.api/2.composables/on-prehydrate.md +1 -1
- package/3.api/2.composables/use-async-data.md +3 -3
- package/3.api/2.composables/use-cookie.md +1 -1
- package/3.api/2.composables/use-fetch.md +2 -2
- package/3.api/2.composables/use-lazy-async-data.md +1 -1
- package/3.api/2.composables/use-lazy-fetch.md +1 -1
- package/3.api/2.composables/use-nuxt-app.md +7 -7
- package/3.api/2.composables/use-nuxt-data.md +4 -4
- package/3.api/2.composables/use-preview-mode.md +1 -1
- package/3.api/2.composables/use-request-fetch.md +1 -1
- package/3.api/2.composables/use-request-header.md +1 -1
- package/3.api/2.composables/use-request-headers.md +1 -1
- package/3.api/2.composables/use-request-url.md +1 -1
- package/3.api/2.composables/use-response-header.md +3 -3
- package/3.api/2.composables/use-route-announcer.md +1 -1
- package/3.api/2.composables/use-route.md +37 -2
- package/3.api/2.composables/use-router.md +5 -5
- package/3.api/2.composables/use-runtime-config.md +1 -1
- package/3.api/2.composables/use-seo-meta.md +3 -3
- package/3.api/2.composables/use-server-seo-meta.md +1 -1
- package/3.api/3.utils/$fetch.md +4 -4
- package/3.api/3.utils/abort-navigation.md +4 -4
- package/3.api/3.utils/add-route-middleware.md +5 -5
- package/3.api/3.utils/call-once.md +2 -2
- package/3.api/3.utils/create-error.md +1 -1
- package/3.api/3.utils/define-nuxt-component.md +2 -2
- package/3.api/3.utils/define-nuxt-route-middleware.md +3 -3
- package/3.api/3.utils/define-page-meta.md +12 -12
- package/3.api/3.utils/define-route-rules.md +1 -1
- package/3.api/3.utils/navigate-to.md +1 -1
- package/3.api/3.utils/on-nuxt-ready.md +1 -1
- package/3.api/3.utils/refresh-cookie.md +1 -1
- package/3.api/3.utils/refresh-nuxt-data.md +2 -2
- package/3.api/3.utils/set-page-layout.md +1 -1
- package/3.api/4.commands/add.md +7 -7
- package/3.api/4.commands/init.md +2 -1
- package/3.api/5.kit/1.modules.md +68 -0
- package/3.api/5.kit/16.layers.md +220 -0
- package/3.api/5.kit/7.pages.md +1 -1
- package/3.api/5.kit/8.layout.md +1 -1
- package/3.api/5.kit/9.plugins.md +1 -1
- package/3.api/6.nuxt-config.md +22 -19
- package/5.community/6.roadmap.md +6 -6
- package/6.bridge/4.plugins-and-middleware.md +3 -3
- package/6.bridge/6.meta.md +1 -1
- package/7.migration/2.configuration.md +2 -2
- package/7.migration/3.auto-imports.md +1 -1
- package/7.migration/5.plugins-and-middleware.md +2 -2
- package/7.migration/6.pages-and-layouts.md +8 -8
- package/7.migration/7.component-options.md +4 -4
- package/7.migration/8.runtime-config.md +1 -1
- package/package.json +1 -1
|
@@ -80,7 +80,7 @@ Returns a Vue `Ref<T>` representing the cookie value. Updating the ref will upda
|
|
|
80
80
|
|
|
81
81
|
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.
|
|
82
82
|
|
|
83
|
-
```vue [app.vue]
|
|
83
|
+
```vue [app/app.vue]
|
|
84
84
|
<script setup lang="ts">
|
|
85
85
|
const counter = useCookie('counter')
|
|
86
86
|
|
|
@@ -17,7 +17,7 @@ It automatically generates a key based on URL and fetch options, provides type h
|
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
19
19
|
|
|
20
|
-
```vue [pages/modules.vue]
|
|
20
|
+
```vue [app/pages/modules.vue]
|
|
21
21
|
<script setup lang="ts">
|
|
22
22
|
const { data, status, error, refresh, clear } = await useFetch('/api/modules', {
|
|
23
23
|
pick: ['title']
|
|
@@ -70,7 +70,7 @@ const { data, status, error, refresh, clear } = await useFetch('/api/auth/login'
|
|
|
70
70
|
|
|
71
71
|
You can use a computed ref or a plain ref as the URL, allowing for dynamic data fetching that automatically updates when the URL changes:
|
|
72
72
|
|
|
73
|
-
```vue [pages/[id\\].vue]
|
|
73
|
+
```vue [app/pages/[id\\].vue]
|
|
74
74
|
<script setup lang="ts">
|
|
75
75
|
const route = useRoute()
|
|
76
76
|
const id = computed(() => route.params.id)
|
|
@@ -20,7 +20,7 @@ By default, [`useAsyncData`](/docs/api/composables/use-async-data) blocks naviga
|
|
|
20
20
|
|
|
21
21
|
## Example
|
|
22
22
|
|
|
23
|
-
```vue [pages/index.vue]
|
|
23
|
+
```vue [app/pages/index.vue]
|
|
24
24
|
<script setup lang="ts">
|
|
25
25
|
/* Navigation will occur before fetching is complete.
|
|
26
26
|
Handle 'pending' and 'error' states directly within your component's template
|
|
@@ -24,7 +24,7 @@ Awaiting `useLazyFetch` in this mode only ensures the call is initialized. On cl
|
|
|
24
24
|
|
|
25
25
|
## Example
|
|
26
26
|
|
|
27
|
-
```vue [pages/index.vue]
|
|
27
|
+
```vue [app/pages/index.vue]
|
|
28
28
|
<script setup lang="ts">
|
|
29
29
|
/* Navigation will occur before fetching is complete.
|
|
30
30
|
* Handle 'pending' and 'error' states directly within your component's template
|
|
@@ -10,7 +10,7 @@ links:
|
|
|
10
10
|
|
|
11
11
|
`useNuxtApp` is a built-in composable that provides a way to access shared runtime context of Nuxt, also known as the [Nuxt context](/docs/guide/going-further/nuxt-app#the-nuxt-context), which is available on both client and server side (but not within Nitro routes). It helps you access the Vue app instance, runtime hooks, runtime config variables and internal states, such as `ssrContext` and `payload`.
|
|
12
12
|
|
|
13
|
-
```vue [app.vue]
|
|
13
|
+
```vue [app/app.vue]
|
|
14
14
|
<script setup lang="ts">
|
|
15
15
|
const nuxtApp = useNuxtApp()
|
|
16
16
|
</script>
|
|
@@ -52,7 +52,7 @@ Hooks available in `nuxtApp` allows you to customize the runtime aspects of your
|
|
|
52
52
|
|
|
53
53
|
See [Runtime Hooks](/docs/api/advanced/hooks#app-hooks-runtime) for available runtime hooks called by Nuxt.
|
|
54
54
|
|
|
55
|
-
```ts [plugins/test.ts]
|
|
55
|
+
```ts [app/plugins/test.ts]
|
|
56
56
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
57
57
|
nuxtApp.hook('page:start', () => {
|
|
58
58
|
/* your code goes here */
|
|
@@ -106,7 +106,7 @@ Nuxt exposes the following properties through `ssrContext`:
|
|
|
106
106
|
- `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.
|
|
107
107
|
|
|
108
108
|
::code-group
|
|
109
|
-
```vue [app.vue]
|
|
109
|
+
```vue [app/app.vue]
|
|
110
110
|
<script setup lang="ts">
|
|
111
111
|
const { data } = await useAsyncData('count', () => $fetch('/api/count'))
|
|
112
112
|
</script>
|
|
@@ -124,7 +124,7 @@ Nuxt exposes the following properties through `ssrContext`:
|
|
|
124
124
|
|
|
125
125
|
- `state` (object) - When you use [`useState`](/docs/api/composables/use-state) composable in Nuxt to set shared state, this state data is accessed through `payload.state.[name-of-your-state]`.
|
|
126
126
|
|
|
127
|
-
```ts [plugins/my-plugin.ts]
|
|
127
|
+
```ts [app/plugins/my-plugin.ts]
|
|
128
128
|
export const useColor = () => useState<string>('color', () => 'pink')
|
|
129
129
|
|
|
130
130
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
@@ -142,7 +142,7 @@ Nuxt exposes the following properties through `ssrContext`:
|
|
|
142
142
|
|
|
143
143
|
In the example below, we define a reducer (or a serializer) and a reviver (or deserializer) for the [Luxon](https://moment.github.io/luxon/#/) DateTime class, using a payload plugin.
|
|
144
144
|
|
|
145
|
-
```ts [plugins/date-time-payload.ts]
|
|
145
|
+
```ts [app/plugins/date-time-payload.ts]
|
|
146
146
|
/**
|
|
147
147
|
* This kind of plugin runs very early in the Nuxt lifecycle, before we revive the payload.
|
|
148
148
|
* You will not have access to the router or other Nuxt-injected properties.
|
|
@@ -164,7 +164,7 @@ Nuxt exposes the following properties through `ssrContext`:
|
|
|
164
164
|
|
|
165
165
|
Use `nuxtApp.isHydrating` (boolean) to check if the Nuxt app is hydrating on the client side.
|
|
166
166
|
|
|
167
|
-
```ts [components/nuxt-error-boundary.ts]
|
|
167
|
+
```ts [app/components/nuxt-error-boundary.ts]
|
|
168
168
|
export default defineComponent({
|
|
169
169
|
setup (_props, { slots, emit }) {
|
|
170
170
|
const nuxtApp = useNuxtApp()
|
|
@@ -185,7 +185,7 @@ You are likely here because you got a "Nuxt instance unavailable" message. Pleas
|
|
|
185
185
|
|
|
186
186
|
The `runWithContext` method is meant to be used to call a function and give it an explicit Nuxt context. Typically, the Nuxt context is passed around implicitly and you do not need to worry about this. However, when working with complex `async`/`await` scenarios in middleware/plugins, you can run into instances where the current instance has been unset after an async call.
|
|
187
187
|
|
|
188
|
-
```ts [middleware/auth.ts]
|
|
188
|
+
```ts [app/middleware/auth.ts]
|
|
189
189
|
export default defineNuxtRouteMiddleware(async (to, from) => {
|
|
190
190
|
const nuxtApp = useNuxtApp()
|
|
191
191
|
let user
|
|
@@ -34,14 +34,14 @@ To use `useNuxtData`, ensure that the data-fetching composable (`useFetch`, `use
|
|
|
34
34
|
|
|
35
35
|
The example below shows how you can use cached data as a placeholder while the most recent data is being fetched from the server.
|
|
36
36
|
|
|
37
|
-
```vue [pages/posts.vue]
|
|
37
|
+
```vue [app/pages/posts.vue]
|
|
38
38
|
<script setup lang="ts">
|
|
39
39
|
// We can access same data later using 'posts' key
|
|
40
40
|
const { data } = await useFetch('/api/posts', { key: 'posts' })
|
|
41
41
|
</script>
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
```vue [pages/posts/[id\\].vue]
|
|
44
|
+
```vue [app/pages/posts/[id\\].vue]
|
|
45
45
|
<script setup lang="ts">
|
|
46
46
|
// Access to the cached value of useFetch in posts.vue (parent route)
|
|
47
47
|
const { data: posts } = useNuxtData('posts')
|
|
@@ -64,14 +64,14 @@ The example below shows how implementing Optimistic Updates can be achieved usin
|
|
|
64
64
|
|
|
65
65
|
Optimistic Updates is a technique where the user interface is updated immediately, assuming a server operation will succeed. If the operation eventually fails, the UI is rolled back to its previous state.
|
|
66
66
|
|
|
67
|
-
```vue [pages/todos.vue]
|
|
67
|
+
```vue [app/pages/todos.vue]
|
|
68
68
|
<script setup lang="ts">
|
|
69
69
|
// We can access same data later using 'todos' key
|
|
70
70
|
const { data } = await useAsyncData('todos', () => $fetch('/api/todos'))
|
|
71
71
|
</script>
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
```vue [components/NewTodo.vue]
|
|
74
|
+
```vue [app/components/NewTodo.vue]
|
|
75
75
|
<script setup lang="ts">
|
|
76
76
|
const newTodo = ref('')
|
|
77
77
|
let previousTodos = []
|
|
@@ -75,7 +75,7 @@ const { enabled, state } = usePreviewMode({
|
|
|
75
75
|
|
|
76
76
|
The example below creates a page where part of a content is rendered only in preview mode.
|
|
77
77
|
|
|
78
|
-
```vue [pages/some-page.vue]
|
|
78
|
+
```vue [app/pages/some-page.vue]
|
|
79
79
|
<script setup>
|
|
80
80
|
const { enabled, state } = usePreviewMode()
|
|
81
81
|
|
|
@@ -24,7 +24,7 @@ The [`useFetch`](/docs/api/composables/use-fetch) composable uses `useRequestFet
|
|
|
24
24
|
|
|
25
25
|
::code-group
|
|
26
26
|
|
|
27
|
-
```vue [pages/index.vue]
|
|
27
|
+
```vue [app/pages/index.vue]
|
|
28
28
|
<script setup lang="ts">
|
|
29
29
|
// This will forward the user's headers to the `/api/cookies` event handler
|
|
30
30
|
// Result: { cookies: { foo: 'bar' } }
|
|
@@ -25,7 +25,7 @@ We can use `useRequestHeader` to easily figure out if a user is authorized or no
|
|
|
25
25
|
|
|
26
26
|
The example below reads the `authorization` request header to find out if a person can access a restricted resource.
|
|
27
27
|
|
|
28
|
-
```ts [middleware/authorized-only.ts]
|
|
28
|
+
```ts [app/middleware/authorized-only.ts]
|
|
29
29
|
export default defineNuxtRouteMiddleware((to, from) => {
|
|
30
30
|
if (!useRequestHeader('authorization')) {
|
|
31
31
|
return navigateTo('/not-authorized')
|
|
@@ -28,7 +28,7 @@ We can use `useRequestHeaders` to access and proxy the initial request's `author
|
|
|
28
28
|
|
|
29
29
|
The example below adds the `authorization` request header to an isomorphic `$fetch` call.
|
|
30
30
|
|
|
31
|
-
```vue [pages/some-page.vue]
|
|
31
|
+
```vue [app/pages/some-page.vue]
|
|
32
32
|
<script setup lang="ts">
|
|
33
33
|
const { data } = await useFetch('/api/confidential', {
|
|
34
34
|
headers: useRequestHeaders(['authorization'])
|
|
@@ -24,7 +24,7 @@ header.value = 'my-value';
|
|
|
24
24
|
|
|
25
25
|
We can use `useResponseHeader` to easily set a response header on a per-page basis.
|
|
26
26
|
|
|
27
|
-
```vue [pages/test.vue]
|
|
27
|
+
```vue [app/pages/test.vue]
|
|
28
28
|
<script setup>
|
|
29
29
|
// pages/test.vue
|
|
30
30
|
const header = useResponseHeader('X-My-Header');
|
|
@@ -37,9 +37,9 @@ header.value = 'my-value';
|
|
|
37
37
|
</template>
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
We can use `useResponseHeader` for example in Nuxt [middleware](/docs/guide/directory-structure/middleware) to set a response header for all pages.
|
|
40
|
+
We can use `useResponseHeader` for example in Nuxt [middleware](/docs/guide/directory-structure/app/middleware) to set a response header for all pages.
|
|
41
41
|
|
|
42
|
-
```ts [middleware/my-header-middleware.ts]
|
|
42
|
+
```ts [app/middleware/my-header-middleware.ts]
|
|
43
43
|
export default defineNuxtRouteMiddleware((to, from) => {
|
|
44
44
|
const header = useResponseHeader('X-My-Always-Header');
|
|
45
45
|
header.value = `I'm Always here!`;
|
|
@@ -51,7 +51,7 @@ Sets the message with `politeness = "assertive"`
|
|
|
51
51
|
|
|
52
52
|
## Example
|
|
53
53
|
|
|
54
|
-
```vue [pages/index.vue]
|
|
54
|
+
```vue [app/pages/index.vue]
|
|
55
55
|
<script setup lang="ts">
|
|
56
56
|
const { message, politeness, set, polite, assertive } = useRouteAnnouncer({
|
|
57
57
|
politeness: 'assertive'
|
|
@@ -12,6 +12,12 @@ links:
|
|
|
12
12
|
Within the template of a Vue component, you can access the route using `$route`.
|
|
13
13
|
::
|
|
14
14
|
|
|
15
|
+
The `useRoute` composable is a wrapper around the identically named composable from `vue-router`, providing access to the current route in a Nuxt application.
|
|
16
|
+
|
|
17
|
+
The key difference is that in Nuxt, the composable ensures that the route is updated **only after** the page content has changed after navigation.
|
|
18
|
+
In contrast, the `vue-router` version updates the route **immediately**, which can lead to synchronization issues between different parts of the template
|
|
19
|
+
that rely on the route metadata, for example.
|
|
20
|
+
|
|
15
21
|
## Example
|
|
16
22
|
|
|
17
23
|
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.
|
|
@@ -45,8 +51,37 @@ Apart from dynamic parameters and query parameters, `useRoute()` also provides t
|
|
|
45
51
|
- `path`: encoded pathname section of the URL
|
|
46
52
|
- `redirectedFrom`: route location that was attempted to access before ending up on the current route location
|
|
47
53
|
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
## Common Pitfalls
|
|
55
|
+
|
|
56
|
+
### Route Synchronization Issues
|
|
57
|
+
|
|
58
|
+
It’s important to use the `useRoute()` composable from Nuxt rather than the one from `vue-router` to avoid synchronization issues during page navigation.
|
|
59
|
+
Importing `useRoute` directly from `vue-router` bypasses Nuxt's implementation.
|
|
60
|
+
|
|
61
|
+
```ts twoslash
|
|
62
|
+
// ❌ do not use `useRoute` from `vue-router`
|
|
63
|
+
// @errors: 2300
|
|
64
|
+
import { useRoute } from 'vue-router'
|
|
65
|
+
// ✅ use Nuxt's `useRoute` composable
|
|
66
|
+
import { useRoute } from '#app'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Calling `useRoute` in Middleware
|
|
70
|
+
|
|
71
|
+
Using `useRoute` in middleware is not recommended because it can lead to unexpected behavior.
|
|
72
|
+
There is no concept of a "current route" in middleware.
|
|
73
|
+
The `useRoute()` composable should only be used in the setup function of a Vue component or in a Nuxt plugin.
|
|
74
|
+
|
|
75
|
+
::warning
|
|
76
|
+
This applies to any composable that uses `useRoute()` internally too.
|
|
50
77
|
::
|
|
51
78
|
|
|
79
|
+
::read-more{to="/docs/4.x/guide/directory-structure/app/middleware"}
|
|
80
|
+
Read more about accessing the route in the middleware section.
|
|
81
|
+
::
|
|
82
|
+
|
|
83
|
+
### Hydration Issues with `route.fullPath`
|
|
84
|
+
|
|
85
|
+
Browsers don't send [URL fragments](https://url.spec.whatwg.org/#concept-url-fragment) (for example `#foo`) when making requests. So using `route.fullPath` to affect the template can trigger hydration issues because this will include the fragment on client but not the server.
|
|
86
|
+
|
|
52
87
|
:read-more{icon="i-simple-icons-vuedotjs" to="https://router.vuejs.org/api/type-aliases/RouteLocationNormalizedLoaded.html"}
|
|
@@ -8,7 +8,7 @@ links:
|
|
|
8
8
|
size: xs
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
```vue [pages/index.vue]
|
|
11
|
+
```vue [app/pages/index.vue]
|
|
12
12
|
<script setup lang="ts">
|
|
13
13
|
const router = useRouter()
|
|
14
14
|
</script>
|
|
@@ -16,13 +16,13 @@ const router = useRouter()
|
|
|
16
16
|
|
|
17
17
|
If you only need the router instance within your template, use `$router`:
|
|
18
18
|
|
|
19
|
-
```vue [pages/index.vue]
|
|
19
|
+
```vue [app/pages/index.vue]
|
|
20
20
|
<template>
|
|
21
21
|
<button @click="$router.back()">Back</button>
|
|
22
22
|
</template>
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
If you have a `pages/` directory, `useRouter` is identical in behavior to the one provided by `vue-router`.
|
|
25
|
+
If you have a `app/pages/` directory, `useRouter` is identical in behavior to the one provided by `vue-router`.
|
|
26
26
|
|
|
27
27
|
::read-more{icon="i-simple-icons-vuedotjs" to="https://router.vuejs.org/api/interfaces/Router.html#Properties-currentRoute" target="_blank"}
|
|
28
28
|
Read `vue-router` documentation about the `Router` interface.
|
|
@@ -78,7 +78,7 @@ Read more about the browser's History API.
|
|
|
78
78
|
|
|
79
79
|
However, Nuxt has a concept of **route middleware** that simplifies the implementation of navigation guards and provides a better developer experience.
|
|
80
80
|
|
|
81
|
-
:read-more{to="/docs/guide/directory-structure/middleware"}
|
|
81
|
+
:read-more{to="/docs/guide/directory-structure/app/middleware"}
|
|
82
82
|
|
|
83
83
|
## Promise and Error Handling
|
|
84
84
|
|
|
@@ -89,4 +89,4 @@ However, Nuxt has a concept of **route middleware** that simplifies the implemen
|
|
|
89
89
|
|
|
90
90
|
## Universal Router Instance
|
|
91
91
|
|
|
92
|
-
If you do not have a `pages/` folder, then [`useRouter`](/docs/api/composables/use-router) will return a universal router instance with similar helper methods, but be aware that not all features may be supported or behave in exactly the same way as with `vue-router`.
|
|
92
|
+
If you do not have a `app/pages/` folder, then [`useRouter`](/docs/api/composables/use-router) will return a universal router instance with similar helper methods, but be aware that not all features may be supported or behave in exactly the same way as with `vue-router`.
|
|
@@ -18,7 +18,7 @@ This is the recommended way to add meta tags to your site as it is XSS safe and
|
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
|
-
```vue [app.vue]
|
|
21
|
+
```vue [app/app.vue]
|
|
22
22
|
<script setup lang="ts">
|
|
23
23
|
useSeoMeta({
|
|
24
24
|
title: 'My Amazing Site',
|
|
@@ -33,7 +33,7 @@ useSeoMeta({
|
|
|
33
33
|
|
|
34
34
|
When inserting tags that are reactive, you should use the computed getter syntax (`() => value`):
|
|
35
35
|
|
|
36
|
-
```vue [app.vue]
|
|
36
|
+
```vue [app/app.vue]
|
|
37
37
|
<script setup lang="ts">
|
|
38
38
|
const title = ref('My title')
|
|
39
39
|
|
|
@@ -56,7 +56,7 @@ In most instances, SEO meta tags don't need to be reactive as search engine robo
|
|
|
56
56
|
|
|
57
57
|
For better performance, you can wrap your `useSeoMeta` calls in a server-only condition when the meta tags don't need to be reactive:
|
|
58
58
|
|
|
59
|
-
```vue [app.vue]
|
|
59
|
+
```vue [app/app.vue]
|
|
60
60
|
<script setup lang="ts">
|
|
61
61
|
if (import.meta.server) {
|
|
62
62
|
// These meta tags will only be added during server-side rendering
|
|
@@ -14,7 +14,7 @@ Just like [`useSeoMeta`](/docs/api/composables/use-seo-meta), `useServerSeoMeta`
|
|
|
14
14
|
|
|
15
15
|
In most instances, the meta doesn't need to be reactive as robots will only scan the initial load. So we recommend using [`useServerSeoMeta`](/docs/api/composables/use-server-seo-meta) as a performance-focused utility that will not do anything (or return a `head` object) on the client.
|
|
16
16
|
|
|
17
|
-
```vue [app.vue]
|
|
17
|
+
```vue [app/app.vue]
|
|
18
18
|
<script setup lang="ts">
|
|
19
19
|
useServerSeoMeta({
|
|
20
20
|
robots: 'index, follow'
|
package/3.api/3.utils/$fetch.md
CHANGED
|
@@ -22,7 +22,7 @@ Using `$fetch` in components without wrapping it with [`useAsyncData`](/docs/api
|
|
|
22
22
|
|
|
23
23
|
We recommend using [`useFetch`](/docs/api/composables/use-fetch) or [`useAsyncData`](/docs/api/composables/use-async-data) + `$fetch` to prevent double data fetching when fetching the component data.
|
|
24
24
|
|
|
25
|
-
```vue [app.vue]
|
|
25
|
+
```vue [app/app.vue]
|
|
26
26
|
<script setup lang="ts">
|
|
27
27
|
// During SSR data is fetched twice, once on the server and once on the client.
|
|
28
28
|
const dataTwice = await $fetch('/api/item')
|
|
@@ -39,7 +39,7 @@ const { data } = await useFetch('/api/item')
|
|
|
39
39
|
|
|
40
40
|
You can use `$fetch` in any methods that are executed only on client-side.
|
|
41
41
|
|
|
42
|
-
```vue [pages/contact.vue]
|
|
42
|
+
```vue [app/pages/contact.vue]
|
|
43
43
|
<script setup lang="ts">
|
|
44
44
|
async function contactForm() {
|
|
45
45
|
await $fetch('/api/contact', {
|
|
@@ -70,7 +70,7 @@ However, during Server-Side Rendering, due to security risks such as **Server-Si
|
|
|
70
70
|
|
|
71
71
|
::code-group
|
|
72
72
|
|
|
73
|
-
```vue [pages/index.vue]
|
|
73
|
+
```vue [app/pages/index.vue]
|
|
74
74
|
<script setup lang="ts">
|
|
75
75
|
// This will NOT forward headers or cookies during SSR
|
|
76
76
|
const { data } = await useAsyncData(() => $fetch('/api/cookies'))
|
|
@@ -87,7 +87,7 @@ export default defineEventHandler((event) => {
|
|
|
87
87
|
|
|
88
88
|
If you need to forward headers and cookies on the server, you must manually pass them:
|
|
89
89
|
|
|
90
|
-
```vue [pages/index.vue]
|
|
90
|
+
```vue [app/pages/index.vue]
|
|
91
91
|
<script setup lang="ts">
|
|
92
92
|
// This will forward the user's headers and cookies to `/api/cookies`
|
|
93
93
|
const requestFetch = useRequestFetch()
|
|
@@ -9,7 +9,7 @@ links:
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
::warning
|
|
12
|
-
`abortNavigation` is only usable inside a [route middleware handler](/docs/guide/directory-structure/middleware).
|
|
12
|
+
`abortNavigation` is only usable inside a [route middleware handler](/docs/guide/directory-structure/app/middleware).
|
|
13
13
|
::
|
|
14
14
|
|
|
15
15
|
## Type
|
|
@@ -30,7 +30,7 @@ abortNavigation(err?: Error | string): false
|
|
|
30
30
|
|
|
31
31
|
The example below shows how you can use `abortNavigation` in a route middleware to prevent unauthorized route access:
|
|
32
32
|
|
|
33
|
-
```ts [middleware/auth.ts]
|
|
33
|
+
```ts [app/middleware/auth.ts]
|
|
34
34
|
export default defineNuxtRouteMiddleware((to, from) => {
|
|
35
35
|
const user = useState('user')
|
|
36
36
|
|
|
@@ -48,7 +48,7 @@ export default defineNuxtRouteMiddleware((to, from) => {
|
|
|
48
48
|
|
|
49
49
|
You can pass the error as a string:
|
|
50
50
|
|
|
51
|
-
```ts [middleware/auth.ts]
|
|
51
|
+
```ts [app/middleware/auth.ts]
|
|
52
52
|
export default defineNuxtRouteMiddleware((to, from) => {
|
|
53
53
|
const user = useState('user')
|
|
54
54
|
|
|
@@ -62,7 +62,7 @@ export default defineNuxtRouteMiddleware((to, from) => {
|
|
|
62
62
|
|
|
63
63
|
You can pass the error as an [`Error`](https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Global_Objects/Error) object, e.g. caught by the `catch`-block:
|
|
64
64
|
|
|
65
|
-
```ts [middleware/auth.ts]
|
|
65
|
+
```ts [app/middleware/auth.ts]
|
|
66
66
|
export default defineNuxtRouteMiddleware((to, from) => {
|
|
67
67
|
try {
|
|
68
68
|
/* code that might throw an error */
|
|
@@ -9,7 +9,7 @@ links:
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
::note
|
|
12
|
-
Route middleware are navigation guards stored in the [`middleware/`](/docs/guide/directory-structure/middleware) directory of your Nuxt application (unless [set otherwise](/docs/api/nuxt-config#middleware)).
|
|
12
|
+
Route middleware are navigation guards stored in the [`app/middleware/`](/docs/guide/directory-structure/app/middleware) directory of your Nuxt application (unless [set otherwise](/docs/api/nuxt-config#middleware)).
|
|
13
13
|
::
|
|
14
14
|
|
|
15
15
|
## Type
|
|
@@ -51,7 +51,7 @@ An optional `options` argument lets you set the value of `global` to `true` to i
|
|
|
51
51
|
|
|
52
52
|
Named route middleware is defined by providing a string as the first argument and a function as the second:
|
|
53
53
|
|
|
54
|
-
```ts [plugins/my-plugin.ts]
|
|
54
|
+
```ts [app/plugins/my-plugin.ts]
|
|
55
55
|
export default defineNuxtPlugin(() => {
|
|
56
56
|
addRouteMiddleware('named-middleware', () => {
|
|
57
57
|
console.log('named middleware added in Nuxt plugin')
|
|
@@ -59,7 +59,7 @@ export default defineNuxtPlugin(() => {
|
|
|
59
59
|
})
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
When defined in a plugin, it overrides any existing middleware of the same name located in the `middleware/` directory.
|
|
62
|
+
When defined in a plugin, it overrides any existing middleware of the same name located in the `app/middleware/` directory.
|
|
63
63
|
|
|
64
64
|
### Global Route Middleware
|
|
65
65
|
|
|
@@ -67,7 +67,7 @@ Global route middleware can be defined in two ways:
|
|
|
67
67
|
|
|
68
68
|
- Pass a function directly as the first argument without a name. It will automatically be treated as global middleware and applied on every route change.
|
|
69
69
|
|
|
70
|
-
```ts [plugins/my-plugin.ts]
|
|
70
|
+
```ts [app/plugins/my-plugin.ts]
|
|
71
71
|
export default defineNuxtPlugin(() => {
|
|
72
72
|
addRouteMiddleware((to, from) => {
|
|
73
73
|
console.log('anonymous global middleware that runs on every route change')
|
|
@@ -77,7 +77,7 @@ Global route middleware can be defined in two ways:
|
|
|
77
77
|
|
|
78
78
|
- Set an optional, third argument `{ global: true }` to indicate whether the route middleware is global.
|
|
79
79
|
|
|
80
|
-
```ts [plugins/my-plugin.ts]
|
|
80
|
+
```ts [app/plugins/my-plugin.ts]
|
|
81
81
|
export default defineNuxtPlugin(() => {
|
|
82
82
|
addRouteMiddleware('global-middleware', (to, from) => {
|
|
83
83
|
console.log('global middleware that runs on every route change')
|
|
@@ -26,7 +26,7 @@ This is useful for code that should be executed only once, such as logging an ev
|
|
|
26
26
|
|
|
27
27
|
The default mode of `callOnce` is to run code only once. For example, if the code runs on the server it won't run again on the client. It also won't run again if you `callOnce` more than once on the client, for example by navigating back to this page.
|
|
28
28
|
|
|
29
|
-
```vue [app.vue]
|
|
29
|
+
```vue [app/app.vue]
|
|
30
30
|
<script setup lang="ts">
|
|
31
31
|
const websiteConfig = useState('config')
|
|
32
32
|
|
|
@@ -39,7 +39,7 @@ await callOnce(async () => {
|
|
|
39
39
|
|
|
40
40
|
It is also possible to run on every navigation while still avoiding the initial server/client double load. For this, it is possible to use the `navigation` mode:
|
|
41
41
|
|
|
42
|
-
```vue [app.vue]
|
|
42
|
+
```vue [app/app.vue]
|
|
43
43
|
<script setup lang="ts">
|
|
44
44
|
const websiteConfig = useState('config')
|
|
45
45
|
|
|
@@ -25,7 +25,7 @@ If you throw an error created with `createError`:
|
|
|
25
25
|
|
|
26
26
|
### Example
|
|
27
27
|
|
|
28
|
-
```vue [pages/movies/[slug\\].vue]
|
|
28
|
+
```vue [app/pages/movies/[slug\\].vue]
|
|
29
29
|
<script setup lang="ts">
|
|
30
30
|
const route = useRoute()
|
|
31
31
|
const { data } = await useFetch(`/api/movies/${route.params.slug}`)
|
|
@@ -22,7 +22,7 @@ Using `<script setup lang="ts">` is the recommended way of declaring Vue compone
|
|
|
22
22
|
|
|
23
23
|
If you choose not to use `setup()` in your app, you can use the `asyncData()` method within your component definition:
|
|
24
24
|
|
|
25
|
-
```vue [pages/index.vue]
|
|
25
|
+
```vue [app/pages/index.vue]
|
|
26
26
|
<script lang="ts">
|
|
27
27
|
export default defineNuxtComponent({
|
|
28
28
|
async asyncData() {
|
|
@@ -40,7 +40,7 @@ export default defineNuxtComponent({
|
|
|
40
40
|
|
|
41
41
|
If you choose not to use `setup()` in your app, you can use the `head()` method within your component definition:
|
|
42
42
|
|
|
43
|
-
```vue [pages/index.vue]
|
|
43
|
+
```vue [app/pages/index.vue]
|
|
44
44
|
<script lang="ts">
|
|
45
45
|
export default defineNuxtComponent({
|
|
46
46
|
head(nuxtApp) {
|
|
@@ -8,7 +8,7 @@ links:
|
|
|
8
8
|
size: xs
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
Route middleware are stored in the [`middleware/`](/docs/guide/directory-structure/middleware) of your Nuxt application (unless [set otherwise](/docs/api/nuxt-config#middleware)).
|
|
11
|
+
Route middleware are stored in the [`app/middleware/`](/docs/guide/directory-structure/app/middleware) of your Nuxt application (unless [set otherwise](/docs/api/nuxt-config#middleware)).
|
|
12
12
|
|
|
13
13
|
## Type
|
|
14
14
|
|
|
@@ -36,7 +36,7 @@ Learn more about available properties of `RouteLocationNormalized` in the **[Vue
|
|
|
36
36
|
|
|
37
37
|
You can use route middleware to throw errors and show helpful error messages:
|
|
38
38
|
|
|
39
|
-
```ts [middleware/error.ts]
|
|
39
|
+
```ts [app/middleware/error.ts]
|
|
40
40
|
export default defineNuxtRouteMiddleware((to) => {
|
|
41
41
|
if (to.params.id === '1') {
|
|
42
42
|
throw createError({ statusCode: 404, statusMessage: 'Page Not Found' })
|
|
@@ -50,7 +50,7 @@ The above route middleware will redirect a user to the custom error page defined
|
|
|
50
50
|
|
|
51
51
|
Use [`useState`](/docs/api/composables/use-state) in combination with `navigateTo` helper function inside the route middleware to redirect users to different routes based on their authentication status:
|
|
52
52
|
|
|
53
|
-
```ts [middleware/auth.ts]
|
|
53
|
+
```ts [app/middleware/auth.ts]
|
|
54
54
|
export default defineNuxtRouteMiddleware((to, from) => {
|
|
55
55
|
const auth = useState('auth')
|
|
56
56
|
|
|
@@ -8,9 +8,9 @@ links:
|
|
|
8
8
|
size: xs
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
`definePageMeta` is a compiler macro that you can use to set metadata for your **page** components located in the [`pages/`](/docs/guide/directory-structure/pages) directory (unless [set otherwise](/docs/api/nuxt-config#pages)). This way you can set custom metadata for each static or dynamic route of your Nuxt application.
|
|
11
|
+
`definePageMeta` is a compiler macro that you can use to set metadata for your **page** components located in the [`app/pages/`](/docs/guide/directory-structure/app/pages) directory (unless [set otherwise](/docs/api/nuxt-config#pages)). This way you can set custom metadata for each static or dynamic route of your Nuxt application.
|
|
12
12
|
|
|
13
|
-
```vue [pages/some-page.vue]
|
|
13
|
+
```vue [app/pages/some-page.vue]
|
|
14
14
|
<script setup lang="ts">
|
|
15
15
|
definePageMeta({
|
|
16
16
|
layout: 'default'
|
|
@@ -18,7 +18,7 @@ definePageMeta({
|
|
|
18
18
|
</script>
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
:read-more{to="/docs/guide/directory-structure/pages#page-metadata"}
|
|
21
|
+
:read-more{to="/docs/guide/directory-structure/app/pages#page-metadata"}
|
|
22
22
|
|
|
23
23
|
## Type
|
|
24
24
|
|
|
@@ -56,7 +56,7 @@ interface PageMeta {
|
|
|
56
56
|
|
|
57
57
|
- **Type**: `string`
|
|
58
58
|
|
|
59
|
-
You may define a name for this page's route. By default, name is generated based on path inside the [`pages/` directory](/docs/guide/directory-structure/pages).
|
|
59
|
+
You may define a name for this page's route. By default, name is generated based on path inside the [`app/pages/` directory](/docs/guide/directory-structure/app/pages).
|
|
60
60
|
|
|
61
61
|
**`path`**
|
|
62
62
|
|
|
@@ -104,7 +104,7 @@ interface PageMeta {
|
|
|
104
104
|
|
|
105
105
|
- **Type**: `MiddlewareKey` | [`NavigationGuard`](https://router.vuejs.org/api/interfaces/NavigationGuard.html#navigationguard) | `Array<MiddlewareKey | NavigationGuard>`
|
|
106
106
|
|
|
107
|
-
Define anonymous or named middleware directly within `definePageMeta`. Learn more about [route middleware](/docs/guide/directory-structure/middleware).
|
|
107
|
+
Define anonymous or named middleware directly within `definePageMeta`. Learn more about [route middleware](/docs/guide/directory-structure/app/middleware).
|
|
108
108
|
|
|
109
109
|
**`pageTransition`**
|
|
110
110
|
|
|
@@ -142,7 +142,7 @@ interface PageMeta {
|
|
|
142
142
|
|
|
143
143
|
- **Type**: `any`
|
|
144
144
|
|
|
145
|
-
Apart from the above properties, you can also set **custom** metadata. You may wish to do so in a type-safe way by [augmenting the type of the `meta` object](/docs/guide/directory-structure/pages/#typing-custom-metadata).
|
|
145
|
+
Apart from the above properties, you can also set **custom** metadata. You may wish to do so in a type-safe way by [augmenting the type of the `meta` object](/docs/guide/directory-structure/app/pages/#typing-custom-metadata).
|
|
146
146
|
|
|
147
147
|
## Examples
|
|
148
148
|
|
|
@@ -154,7 +154,7 @@ The example below demonstrates:
|
|
|
154
154
|
- how `keepalive` property makes sure that the `<modal>` component is not cached when switching between multiple components;
|
|
155
155
|
- adding `pageType` as a custom property:
|
|
156
156
|
|
|
157
|
-
```vue [pages/some-page.vue]
|
|
157
|
+
```vue [app/pages/some-page.vue]
|
|
158
158
|
<script setup lang="ts">
|
|
159
159
|
definePageMeta({
|
|
160
160
|
key: (route) => route.fullPath,
|
|
@@ -170,9 +170,9 @@ definePageMeta({
|
|
|
170
170
|
|
|
171
171
|
### Defining Middleware
|
|
172
172
|
|
|
173
|
-
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:
|
|
173
|
+
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 `app/middleware/` directory:
|
|
174
174
|
|
|
175
|
-
```vue [pages/some-page.vue]
|
|
175
|
+
```vue [app/pages/some-page.vue]
|
|
176
176
|
<script setup lang="ts">
|
|
177
177
|
definePageMeta({
|
|
178
178
|
// define middleware as a function
|
|
@@ -207,7 +207,7 @@ The two routes "/test-category" and "/1234-post" match both `[postId]-[postSlug]
|
|
|
207
207
|
|
|
208
208
|
To make sure that we are only matching digits (`\d+`) for `postId` in the `[postId]-[postSlug]` route, we can add the following to the `[postId]-[postSlug].vue` page template:
|
|
209
209
|
|
|
210
|
-
```vue [pages/[postId\\]-[postSlug\\].vue]
|
|
210
|
+
```vue [app/pages/[postId\\]-[postSlug\\].vue]
|
|
211
211
|
<script setup lang="ts">
|
|
212
212
|
definePageMeta({
|
|
213
213
|
path: '/:postId(\\d+)-:postSlug'
|
|
@@ -219,9 +219,9 @@ For more examples see [Vue Router's Matching Syntax](https://router.vuejs.org/gu
|
|
|
219
219
|
|
|
220
220
|
### Defining Layout
|
|
221
221
|
|
|
222
|
-
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`:
|
|
222
|
+
You can define the layout that matches the layout's file name located (by default) in the [`app/layouts/` directory](/docs/guide/directory-structure/app/layouts). You can also disable the layout by setting the `layout` to `false`:
|
|
223
223
|
|
|
224
|
-
```vue [pages/some-page.vue]
|
|
224
|
+
```vue [app/pages/some-page.vue]
|
|
225
225
|
<script setup lang="ts">
|
|
226
226
|
definePageMeta({
|
|
227
227
|
// set custom layout
|