app.vue
Nuxt 3 provides a central entry point to your app via~/app.vue.
If you don’t have an
app.vue file in your source directory, Nuxt will use its own default version.app.vue instead.
Creating app.vue
Consider creating anapp.vue file and including any logic that needs to run once at the top-level of your app:
app.vue
Layouts
If you are using layouts in your app for multiple pages, there is only a slight change required. In Nuxt 2, the<Nuxt> component is used within a layout to render the current page. In Nuxt 3, layouts use slots instead, so you will have to replace that component with a <slot />. This also allows advanced use cases with named and scoped slots.
You will also need to change how you define the layout used by a page using the definePageMeta compiler macro. Layouts will be kebab-cased. So app/layouts/customLayout.vue becomes custom-layout when referenced in your page.
Migration Steps
- Replace
<Nuxt />with<slot />
app/layouts/custom.vue
- Use
definePageMetato select the layout used by your page
app/pages/index.vue
- Move
~/layouts/_error.vueto~/error.vue
<NuxtLayout> directly within error.vue:
error.vue
Pages
Nuxt 3 ships with an optionalvue-router integration triggered by the existence of a app/pages/ directory in your source directory. If you only have a single page, you may consider instead moving it to app.vue for a lighter build.
Dynamic Routes
The format for defining dynamic routes in Nuxt 3 is slightly different from Nuxt 2, so you may need to rename some of the files withinapp/pages/.
- Where you previously used
_idto define a dynamic route parameter, you now use[id]. - Where you previously used
_.vueto define a catch-all route, you now use[...slug].vue.
Dynamic Routes Example
Nested Routes
In Nuxt 2, you will have defined any nested routes (with parent and child components) using<Nuxt> and <NuxtChild>. In Nuxt 3, these have been replaced with a single <NuxtPage> component.
Nested Routes Example
Page Keys and Keep-alive Props
If you were passing a custom page key or keep-alive props to<Nuxt>, you will now use definePageMeta to set these options.
Page and Layout Transitions
If you have been defining transitions for your page or layout directly in your component options, you will now need to usedefinePageMeta to set the transition. Since Vue 3, -enter and -leave CSS classes have been renamed. The style prop from <Nuxt> no longer applies to transition when used on <slot>, so move the styles to your -active class.
NuxtLink Component
Most of the syntax and functionality are the same for the globalNuxtLink component. If you have been using the shortcut <NLink> format, you should update this to use <NuxtLink>.
<NuxtLink> is now a drop-in replacement for all links, even external ones.
Programmatic Navigation
When migrating from Nuxt 2 to Nuxt 3, you will have to update how you programmatically navigate your users. In Nuxt 2, you had access to the underlying Vue Router withthis.$router. In Nuxt 3, you can use the navigateTo() utility method which allows you to pass a route and parameters to Vue Router.
Migration Checklist
- Rename any pages with dynamic parameters to match the new format (
_id→[id]) - Update
<Nuxt>and<NuxtChild>to be<NuxtPage> - Replace
<Nuxt />with<slot />in layouts - If you’re using the Composition API, migrate
this.$routeandthis.$routerto useuseRouteanduseRoutercomposables - Update
<NLink>to<NuxtLink> - Move layout definitions from component options to
definePageMeta