> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/nuxt/nuxt/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration Migration

> Learn how to migrate your Nuxt 2 configuration to Nuxt 3's new configuration system.

The starting point for your Nuxt app remains your `nuxt.config` file.

<Note>
  Nuxt configuration will be loaded using [`unjs/jiti`](https://github.com/unjs/jiti) and [`unjs/c12`](https://github.com/unjs/c12).
</Note>

## Migrate to defineNuxtConfig

You should migrate to the new `defineNuxtConfig` function that provides a typed configuration schema.

<CodeGroup>
  ```ts Nuxt 2 theme={null}
  export default {
    // ...
  }
  ```

  ```ts Nuxt 3 theme={null}
  export default defineNuxtConfig({
    // ...
  })
  ```
</CodeGroup>

## Router Configuration

### Extending Routes

If you were using `router.extendRoutes`, migrate to the new `pages:extend` hook:

<CodeGroup>
  ```ts Nuxt 2 theme={null}
  export default {
    router: {
      extendRoutes (routes) {
        //
      },
    },
  }
  ```

  ```ts Nuxt 3 theme={null}
  export default defineNuxtConfig({
    hooks: {
      'pages:extend' (routes) {
        //
      },
    },
  })
  ```
</CodeGroup>

### Route Name Splitter

If you were using `router.routeNameSplitter`, you can achieve the same result by updating route name generation logic in the new `pages:extend` hook:

<CodeGroup>
  ```ts Nuxt 2 theme={null}
  export default {
    router: {
      routeNameSplitter: '/',
    },
  }
  ```

  ```ts Nuxt 3 theme={null}
  import { createResolver } from '@nuxt/kit'

  export default defineNuxtConfig({
    hooks: {
      'pages:extend' (routes) {
        const routeNameSplitter = '/'
        const root = createResolver(import.meta.url).resolve('./pages')

        function updateName (routes) {
          if (!routes) {
            return
          }

          for (const route of routes) {
            const relativePath = route.file.substring(root.length + 1)
            route.name = relativePath.slice(0, -4).replace(/\/index$/, '').replace(/\//g, routeNameSplitter)

            updateName(route.children)
          }
        }
        updateName(routes)
      },
    },
  })
  ```
</CodeGroup>

## ESM Syntax

Nuxt 3 is an ESM native framework. Although [`unjs/jiti`](https://github.com/unjs/jiti) provides semi compatibility when loading `nuxt.config` file, avoid any usage of `require` and `module.exports` in this file.

1. Change `module.exports` to `export default`
2. Change `const lib = require('lib')` to `import lib from 'lib'`

## Async Configuration

<Warning>
  In order to make Nuxt loading behavior more predictable, async config syntax is deprecated. Consider using Nuxt hooks for async operations.
</Warning>

## Environment Variables

Nuxt has built-in support for loading `.env` files. Avoid directly importing it from `nuxt.config`.

## Modules

Nuxt and Nuxt modules are now build-time-only.

### Migration Steps

1. **Move all your `buildModules` into `modules`** - There is no longer a distinction between build and runtime modules.
2. **Check for Nuxt 3 compatibility of modules** - Some modules may need updates.
3. **Update local module paths** - If you have any local modules pointing to a directory, update this to point to the entry file:

```diff theme={null}
export default defineNuxtConfig({
  modules: [
-   '~/modules/my-module'
+   '~/modules/my-module/index'
  ]
})
```

<Tip>
  If you are a module author, you can check out more information about module compatibility and our module author guide.
</Tip>

## Directory Changes

The `static/` directory (for storing static assets) has been renamed to `public/`. You can either rename your `static` directory to `public`, or keep the name by setting `dir.public` in your `nuxt.config`.

## TypeScript

It will be much easier to migrate your application if you use Nuxt's TypeScript integration. This does not mean you need to write your application in TypeScript, just that Nuxt will provide automatic type hints for your editor.

<Note>
  Nuxt can type-check your app using [`vue-tsc`](https://github.com/vuejs/language-tools/tree/master/packages/tsc) with `nuxt typecheck` command.
</Note>

### Setup TypeScript

1. Create a `tsconfig.json` with the following content:

```json theme={null}
{
  "files": [],
  "references": [
    {
      "path": "./.nuxt/tsconfig.app.json"
    },
    {
      "path": "./.nuxt/tsconfig.server.json"
    },
    {
      "path": "./.nuxt/tsconfig.shared.json"
    },
    {
      "path": "./.nuxt/tsconfig.node.json"
    }
  ]
}
```

2. Run `npx nuxt prepare` to generate the tsconfig files.
3. Install Volar following the instructions in the docs.

## Vue Changes

There are a number of changes to what is recommended Vue best practice, as well as a number of breaking changes between Vue 2 and 3.

It is recommended to read the [Vue 3 migration guide](https://v3-migration.vuejs.org) and in particular the [breaking changes list](https://v3-migration.vuejs.org/breaking-changes/).

<Warning>
  It is not currently possible to use the [Vue 3 migration build](https://v3-migration.vuejs.org/migration-build.html) with Nuxt 3.
</Warning>

## Vuex

Nuxt no longer provides a Vuex integration. Instead, the official Vue recommendation is to use `pinia`, which has built-in Nuxt support via a Nuxt module.

### Migrate to Pinia

A simple way to provide global state management with pinia:

1. Install the `@pinia/nuxt` module:

```bash theme={null}
yarn add pinia @pinia/nuxt
```

2. Enable the module in your nuxt configuration:

```ts theme={null}
import { defineNuxtConfig } from 'nuxt/config'

export default defineNuxtConfig({
  modules: ['@pinia/nuxt'],
})
```

3. Create a `store` folder at the root of your application:

```ts store/index.ts theme={null}
import { defineStore } from 'pinia'

export const useMainStore = defineStore('main', {
  state: () => ({
    counter: 0,
  }),
  actions: {
    increment () {
      // `this` is the store instance
      this.counter++
    },
  },
})
```

4. Create a plugin file to globalize your store:

```ts app/plugins/pinia.ts theme={null}
import { useMainStore } from '~/store'

export default defineNuxtPlugin(({ $pinia }) => {
  return {
    provide: {
      store: useMainStore($pinia),
    },
  }
})
```

### Keep Using Vuex

If you want to keep using Vuex, you can manually migrate to Vuex 4 following [these steps](https://vuex.vuejs.org/guide/migrating-to-4-0-from-3-x.html).

Once it's done, you will need to add the following plugin to your Nuxt app:

```ts app/plugins/vuex.ts theme={null}
import store from '~/store'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(store)
})
```

For larger apps, this migration can entail a lot of work. If updating Vuex still creates roadblocks, you may want to use the community module: [nuxt3-vuex-module](https://github.com/vedmant/nuxt3-vuex#nuxt3-vuex-module), which should work out of the box.
