new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Nuxt · Getting started · all subjects

routing

83 notes in this subject, read out of this brain and free to use. This is page 1 of 2.

File-based routing in Nuxt

Nuxt uses file-based routing where routes are automatically defined based on the structure of the app/pages/ directory. This eliminates the need for manual route configuration.

Pages directory creates routes

Every file in the app/pages/ directory represents a different route and displays its content. Files are tied to specific route patterns.

Enable pages with NuxtPage component

To use pages, create an app/pages/index.vue file and add the <NuxtPage /> component to app.vue, or remove app.vue entirely to use the default entry point.

Pages routing example

Pages create routes based on filenames: app/pages/index.vue displays at the / route app/pages/about.vue displays at the /about route Example: ```vue [app/pages/index.vue] <template> <div> <h1>Welcome to the homepage</h1> </div> </template> ``` ```vue [app/pages/about.vue] <template> <section> <p>This page will be displayed at the /about route.</p> </section> </template> ```

definePageMeta with useHead for route-based metadata

Within your `app/pages/` directory, you can use `definePageMeta` along with `useHead` to set metadata based on the current route. In `definePageMeta`, set the title (this is extracted at build time via a macro, so it can't be set dynamically). Then in your layout file, use the route's metadata with `const route = useRoute()` to access `route.meta.title`.

File system routing creates routes from pages/ directory

Nuxt file-system routing creates a route for every Vue file in the app/pages/ directory. Each file automatically generates a corresponding URL (or route) that displays the contents of the file.

Code-splitting is enabled by default in routing

Code-splitting is enabled by default in Nuxt routing. By using dynamic imports for each page, Nuxt leverages code-splitting to ship the minimum amount of JavaScript for the requested route.

Disable code-splitting in nuxt.config.ts

To disable code-splitting and ship all JavaScript in a single file, set vite.$client.build.rolldownOptions.output.codeSplitting to false in nuxt.config.ts. This is rarely beneficial and usually increases initial download, so only disable it if you have measured that it helps your case.

Naming conventions for dynamic and nested routes

Nuxt file system routing uses naming conventions to create dynamic and nested routes. Square brackets in filenames create dynamic segments, for example pages/posts/[id].vue generates the route /posts/:id.

about.vue, index.vue page routing example

A directory structure with pages/about.vue, pages/index.vue, and pages/posts/[id].vue generates routes /about, /, and /posts/:id respectively.

NuxtLink component for navigation

The NuxtLink component links pages between them. It renders an <a> tag with the href attribute set to the route of the page. Once the application is hydrated, page transitions are performed in JavaScript by updating the browser URL, which prevents full-page refreshes and allows for animated transitions.

NuxtLink prefetching behavior

When a NuxtLink enters the viewport on the client side, Nuxt will automatically prefetch components and payload (generated pages) of the linked pages ahead of time, resulting in faster navigation.

useRoute composable accesses 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. For example, route.params.id accesses the id parameter from a dynamic route like /posts/1.

Three kinds of route middleware

Nuxt provides three kinds of route middleware: (1) Anonymous (inline) route middleware defined directly in pages where they are used, (2) Named route middleware placed in app/middleware/ directory and automatically loaded via asynchronous import when used on a page (route middleware names are normalized to kebab-case, so someMiddleware becomes some-middleware), and (3) Global route middleware placed in app/middleware/ directory with a .global suffix and automatically run on every route change.

Route validation example for numeric id parameter

Example of route validation: definePageMeta({ validate(route) { return typeof route.params.id === 'string' && /^\d+$/.test(route.params.id) } }) checks if the id parameter consists only of digits.

Route middleware runs only in Vue, not on server routes

Route middleware runs within the Vue part of a Nuxt app and does not run for server routes (e.g. /api/*) or other server requests. To apply middleware to server requests, use server middleware instead.

Route validation with definePageMeta validate

Nuxt offers route validation via the validate property in definePageMeta() in each page you wish to validate. The validate property accepts the route as an argument and returns a boolean to determine whether the route is valid. Returning false causes a 404 error. You can also return an object with status/statusText to customize the error.

definePageMeta with middleware property

Named route middleware is applied to a page using definePageMeta with the middleware property set to the middleware name, for example middleware: 'auth' applies the auth middleware to that page.

defineNuxtRouteMiddleware creates route middleware

Route middleware is created using defineNuxtRouteMiddleware which takes a callback function with (to, from) arguments. Anonymous middleware is defined directly in pages using this function.

Page transition with NuxtPage example

This example shows how to add CSS transitions to pages in app.vue: ```vue <template> <NuxtPage /> </template> <style> .page-enter-active, .page-leave-active { transition: all 0.4s; } .page-enter-from, .page-leave-to { opacity: 0; filter: blur(1rem); } </style> ```

Vue Transition component requirement

Nuxt uses Vue's `<Transition>` component to apply transitions between pages and layouts.

Single root element requirement for transitions

A page or layout you want to animate must have a single root element. Pages or layouts with multiple root elements (fragments) cannot be animated and transitions will not run. When navigating between routes, multiple root elements may error. Wrap the template in a single root element such as a `<div>`.

Enable page transitions in nuxt.config

To enable page transitions globally, add `pageTransition` to the `app` object in `nuxt.config.ts`. Example: `export default defineNuxtConfig({ app: { pageTransition: { name: 'page', mode: 'out-in' } } })`

Layout transition takes precedence over page transition

If you are changing layouts as well as pages, the page transition will not run. Instead, set a layout transition using the `layoutTransition` option.

Page transition CSS classes

Page transitions use CSS classes based on the transition name. For a transition named 'page', the classes are: `.page-enter-active`, `.page-leave-active`, `.page-enter-from`, `.page-leave-to`. These classes control the animation timing and effects.

Override transition for specific page with definePageMeta

To set a different transition for a single page, use `definePageMeta({ pageTransition: { name: 'rotate' } })` in the page component. This overrides the global page transition.

Enable layout transitions in nuxt.config

To enable layout transitions globally, add `layoutTransition` to the `app` object in `nuxt.config.ts`. Example: `export default defineNuxtConfig({ app: { layoutTransition: { name: 'layout', mode: 'out-in' } } })`

Layout transition CSS classes

Layout transitions use CSS classes based on the transition name. For a transition named 'layout', the classes are: `.layout-enter-active`, `.layout-leave-active`, `.layout-enter-from`, `.layout-leave-to`. These classes control the animation timing and effects.

Override layout transition per page with definePageMeta

To set a custom layout transition for a specific page, use `definePageMeta({ layout: 'orange', layoutTransition: { name: 'slide-in' } })` to override the global layout transition.

Rename CSS classes when changing transition name

If you change the `name` property of a transition in `nuxt.config`, you must also rename the corresponding CSS classes accordingly. For example, if changing from `name: 'page'` to `name: 'fade'`, rename `.page-enter-active` to `.fade-enter-active`.

Override global transition with definePageMeta

Use `definePageMeta` to define page or layout transitions for a single page and override any transitions defined globally in `nuxt.config`. Per-page settings take precedence over global settings.

Disable pageTransition and layoutTransition per page

To disable transitions for a specific page, use `definePageMeta({ pageTransition: false, layoutTransition: false })`.

Disable transitions globally

To disable page and layout transitions globally, add the following to `nuxt.config.ts`: `export default defineNuxtConfig({ app: { pageTransition: false, layoutTransition: false } })`

JavaScript hooks for custom transitions

For advanced transitions, use JavaScript hooks in `definePageMeta`: `onBeforeEnter(el)`, `onEnter(el, done)`, and `onAfterEnter(el)`. These hooks are useful with JavaScript animation libraries like GSAP.

Dynamic transitions with middleware

To apply dynamic transitions based on conditional logic, use inline middleware in `definePageMeta` to assign a different transition name to `to.meta.pageTransition`. This allows transitions to change based on route parameters or conditions.

Configure transition via NuxtPage prop

When using `<NuxtPage />` in `app.vue`, you can configure transitions globally with the `transition` prop: `<NuxtPage :transition="{ name: 'bounce', mode: 'out-in' }" />`. This page transition cannot be overridden with `definePageMeta` on individual pages.

Enable View Transitions API (experimental)

To enable the experimental View Transitions API, add `experimental: { viewTransition: true }` to `nuxt.config.ts`. This implements native browser transitions that can transition between unrelated elements on different pages.

View Transitions API respects prefers-reduced-motion

When `viewTransition` is set to `true` in `nuxt.config.ts`, Nuxt will not apply transitions if the user's browser matches `prefers-reduced-motion: reduce`. Set to `'always'` to apply transitions regardless of user preference.

Disable View Transitions globally and opt-in per page

To disable view transitions globally and enable them only for specific pages, set `app: { viewTransition: false }` in `nuxt.config.ts`, then use `definePageMeta({ viewTransition: true })` on individual pages.

Override View Transitions per page

To disable view transitions for a specific page, use `definePageMeta({ viewTransition: false })`. Per-page overrides only take effect if `experimental.viewTransition` is enabled in `nuxt.config.ts`.

View Transition types configuration

View transition types allow you to apply different CSS animations depending on navigation type. Set default types globally in `nuxt.config.ts`: `app: { viewTransition: { enabled: true, types: ['slide'] } }`

View Transition types per page with definePageMeta

Configure view transition types per page using `definePageMeta` with: `types` (applied to any transition involving this page), `toTypes` (applied only when navigating TO this page), and `fromTypes` (applied only when navigating FROM this page). Each can be a static array or a function for dynamic behavior.

Dynamic view transition types with functions

In `definePageMeta`, you can use functions for `types`, `toTypes`, and `fromTypes` to determine types dynamically based on the route. Example: `toTypes: (to, from) => Number(to.params.id) > Number(from.params.id) ? ['slide-left'] : ['slide-right']`. Functions only work in `definePageMeta`, not in `nuxt.config.ts`.

Target view transition types in CSS

Use the `:active-view-transition-type()` pseudo-class selector in CSS to target specific view transition types. Example: `html:active-view-transition-type(slide-left) { &::view-transition-old(root) { animation: slide-out-left 0.3s ease-in-out; } }`

page:view-transition:start hook

The `page:view-transition:start` hook provides access to the `ViewTransition` object and its `types` property (`ViewTransitionTypeSet`), which can be read or modified at runtime. Access it in a plugin with: `nuxtApp.hook('page:view-transition:start', (transition) => { console.log([...transition.types]) })`

Disable Vue transitions when View Transitions API is supported

To disable Vue transitions (`pageTransition` and `layoutTransition`) when the browser supports the View Transitions API, create a middleware file `~/middleware/disable-vue-transitions.global.ts` that checks `document.startViewTransition` and sets `to.meta.pageTransition = false` and `to.meta.layoutTransition = false`.

View Transitions API limitation with data fetching

If you perform data fetching within page setup functions, reconsider using the View Transitions API feature. By design, View Transitions freeze DOM updates while they are taking place, which can cause issues with concurrent data fetching.

Custom page transition example with rotate

This example shows how to define a custom page transition with 3D rotation in a specific page: ```vue <script setup lang="ts"> definePageMeta({ pageTransition: { name: 'rotate', }, }) </script> ``` With CSS: ```css .rotate-enter-active, .rotate-leave-active { transition: all 0.4s; } .rotate-enter-from, .rotate-leave-to { opacity: 0; transform: rotate3d(1, 1, 1, 15deg); } ```

Layout transition example

This example shows how to set up layout transitions with CSS in app.vue: ```vue <template> <NuxtLayout> <NuxtPage /> </NuxtLayout> </template> <style> .layout-enter-active, .layout-leave-active { transition: all 0.4s; } .layout-enter-from, .layout-leave-to { filter: grayscale(1); } </style> ```

Dynamic transitions with middleware example

This example shows how to apply dynamic transitions based on route parameters using inline middleware: ```vue <script setup lang="ts"> definePageMeta({ pageTransition: { name: 'slide-right', mode: 'out-in', }, middleware (to, from) { if (to.meta.pageTransition && typeof to.meta.pageTransition !== 'boolean') { to.meta.pageTransition.name = +to.params.id! > +from.params.id! ? 'slide-left' : 'slide-right' } }, }) </script> <template> <h1>#{{ $route.params.id }}</h1> </template> <style> .slide-left-enter-active, .slide-left-leave-active, .slide-right-enter-active, .slide-right-leave-active { transition: all 0.2s; } .slide-left-enter-from { opacity: 0; transform: translate(50px, 0); } .slide-left-leave-to { opacity: 0; transform: translate(-50px, 0); } .slide-right-enter-from { opacity: 0; transform: translate(-50px, 0); } .slide-right-leave-to { opacity: 0; transform: translate(50px, 0); } </style> ```

View Transition types CSS targeting example

This example shows how to target different view transition types in CSS: ```css /* Default crossfade */ ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.3s; } /* Slide left animation */ html:active-view-transition-type(slide-left) { &::view-transition-old(root) { animation: slide-out-left 0.3s ease-in-out; } &::view-transition-new(root) { animation: slide-in-right 0.3s ease-in-out; } } /* Slide right animation */ html:active-view-transition-type(slide-right) { &::view-transition-old(root) { animation: slide-out-right 0.3s ease-in-out; } &::view-transition-new(root) { animation: slide-in-left 0.3s ease-in-out; } } ```

Migrate router.extendRoutes to pages:extend hook

In Nuxt 2, the router.extendRoutes configuration option was used to modify routes. In Nuxt 3, this has been replaced with the 'pages:extend' hook in the hooks configuration object.

Migrate router.routeNameSplitter to pages:extend hook

In Nuxt 2, router.routeNameSplitter was used to customize route name generation. In Nuxt 3, you can achieve the same result by updating route name generation logic within the 'pages:extend' hook.

NuxtLink replaces NLink shortcut

In Nuxt 3, <NuxtLink> is the standard component for all links, including external ones. If you were using the <NLink> shortcut format in Nuxt 2, update it to use <NuxtLink>.

Catch-all routes syntax change from _.vue to [...slug].vue

In Nuxt 3, catch-all routes use [...slug].vue format instead of _.vue. For example, /pages/users/_.vue becomes /pages/users/[...slug].vue, and the parameter is accessed via params.slug.

NuxtPage replaces Nuxt and NuxtChild components

In Nuxt 3, the <NuxtPage> component replaces both <Nuxt> and <NuxtChild> components for rendering nested routes with parent and child components.

Page key and keep-alive props via definePageMeta

In Nuxt 3, use definePageMeta to set page key and keep-alive props instead of passing them to <Nuxt>. The key property can be a function like route => route.slug, and keepalive property accepts exclude array like { exclude: ['modal'] }.

Page and layout transitions via definePageMeta

In Nuxt 3, define transitions for pages or layouts using definePageMeta instead of component options. Provide a transition property with name, like definePageMeta({ transition: { name: 'page' } }). Since Vue 3, -enter and -leave CSS classes have been renamed, and you should move transition styles to your -active class.

navigateTo() replaces this.$router.push()

In Nuxt 3, use the navigateTo() utility method for programmatic navigation instead of this.$router.push(). Always await navigateTo() or return its result from functions. Example: navigateTo({ path: '/search', query: { name: 'first name', type: '1' } })

Nuxt 3 definePageMeta with NuxtPage example

In Nuxt 3, use definePageMeta in a parent component with NuxtPage child component like this: definePageMeta({ key: route => route.slug, transition: { name: 'page' }, keepalive: { exclude: ['modal'] } }) replaces Nuxt 2's NuxtChild with keep-alive, keep-alive-props, and nuxt-child-key.

Give your agent this brain