Upgrading to Nuxt 4
Tags: nuxt, javascript, vue, frontend
Published: 2024-06-24 21:53:35

---
title: Upgrading to Nuxt 4
published: true
date: 2024-06-24 10:48:49 UTC
tags: nuxt,javascript,vue,frontenddevelopment
canonical_url: https://www.vuemastery.com/blog/upgrading-to-nuxt-4
---

![](https://cdn-images-1.medium.com/max/1024/1*Qrd_wR2gjCfwI0RX-RQHSg.jpeg)

Nuxt v4 is coming out soon. This version of Nuxt is predominantly about performance upgrades and API consistency. Although there are no ground-breaking user-facing changes, we'll still go through them one by one in this tutorial to make sure your Nuxt v3 app can still run on v4.

---

At the time of this writing, nuxt v4 has not been released yet. But you can still try it out using v3.12.

First, upgrade the Nuxt version in your app:

```
npx nuxi@latest upgrade
```

This will upgrade your project to the latest Nuxt version.

With v3.12, you have to set the `compatibilityVersion` option to `4`:
**nuxt.config.ts**

```tsx
export default defineNuxtConfig({
  future: {
    compatibilityVersion: 4
  },
  ...
})
```

Next, let's talk about the changes you should be expecting in Nuxt 4.

---

## Nuxt 4 Folder Structure

The most obvious change in Nuxt v4 is the new folder structure:

![folder_structure.png](https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2F1.1719254486707.jpg?alt=media&token=5e849d7f-a737-47ee-aa1b-2518a3de365d)

Now you have to put the client-side code in the **app** folder instead of the root folder. But the server folder can stay where it is.

This change would require you to move some of your files around, but this change is optional. If you don't do it, Nuxt can still detect it and use the old way.

This is a performance upgrade because the file watchers don't have to watch all the files in the root folder. Secondly, this is also a DX upgrade because IDEs can provide better support with client code and server code separated in their own folders. For instance, server code is usually running in a Node.js environment, and the client code is running in a browser environment. Separating the two different types of code means that the IDE can be configured for each folder separately.

---

## useAsyncData & useFetch

There are a handful of miscellaneous changes with `useAsyncData` and `useFetch` that you need to be mindful of.

First of all, the data fetched using `useAsyncData` and `useFetch` will be cached and made available to other pre-rendered pages without refetching. 

![cached_shared.png](https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2F2.1719254486708.jpg?alt=media&token=a6f8eeaa-ac3b-492d-adb4-3535d20aea4b)

This data-sharing feature has been experimental, but in Nuxt 4, it’s a real feature.

---

The data ref that gets returned will now be a shallow ref:

![shallowref.png](https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2F3.1719254491623.jpg?alt=media&token=34ce9561-8585-4f6f-9b8d-12254f3f3f77)

(Shallow ref will only be reactive if the `.value` itself is reassigned.)

---

Both of these composables also return a `refresh` function that you can call to refetch the data. And this `refresh` function can be configured with a `dedupe` option:

![refresh_dedupe.png](https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2F4.1719254495785.jpg?alt=media&token=fe5b595c-3f5c-44cc-9a90-2976f98f3418)

Instead of using `true` and `false`, now you have to use `cancel` or `defer` to set the `dedupe` option. Cancel means cancelling the duplicated request (the new one), and defer means wait for the existing one to finish before executing the new one.

---

When `useAsyncData` is configured with a default value, `refreshNuxtData` will reset the data back to that default value:

![useAsyncData_clearNuxtData.png](https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2F5.1719254499632.jpg?alt=media&token=44f96b50-ae89-4f1d-a7b8-303f2d2eff1c)

(Previously, this would reset the `comments` to `undefined`. And since `useFetch` couldn’t be configured with a default value, this doesn’t affect `useFetch`.)

---

On a related note, if you didn’t set a default value, it will now default to `undefined`. This applies to both `useAsyncData` and `useFetch`:

![undefined_by_default.png](https://firebasestorage.googleapis.com/v0/b/vue-mastery.appspot.com/o/flamelink%2Fmedia%2F6.1719254499633.jpg?alt=media&token=dfe19489-9034-457f-8dce-362d7310f54e)

(Previously, it defaults to `null`.)

---

## Other Nuxt 4 Changes

Finally, there are changes that don't affect most projects so you probably don't need to worry about them. But I include them here for completeness:

- Now Nuxt scans the **index.js** files in the child folders inside **/middleware**.
- Now the `builder:watch` hook emits an absolute path, instead of a relative path.
- Some template-specific code generation utils have been removed, and **.ejs** file compilation is removed, too.
- Some experimental features have also been removed, so their corresponding config options have been removed too: `treeshakeClientOnly`, `configSchema`, `polyfillVueUseHead`, `respectNoSSRHeader`.

---

## Where to go next?

From a framework user standpoint, Nuxt 3 and Nuxt 4 are basically the same Nuxt. You can think of Nuxt 4 as a more fleshed out version of Nuxt 3. This is great because you can still use most of the Nuxt 3 learning materials currently available. 

If you enjoy visually illustrated content like this tutorial, you should check out the <a href="https://www.vuemastery.com/courses/real-world-nuxt-3/intro" target="_blank" rel="noopener noreferrer">Real World Nuxt</a> course and the <a href="https://www.vuemastery.com/courses/nuxt-api-routes/api-routes-introduction" target="_blank" rel="noopener noreferrer">Nuxt API Routes</a> course here on <a href="https://www.vuemastery.com" target="_blank" rel="noopener noreferrer">VueMastery.com</a>.
_Originally published at_ [_https://www.vuemastery.com_](https://www.vuemastery.com/blog/upgrading-to-nuxt-4) _on June 24, 2024._

* * *