Nuxt 4 en 2026 : nouvelle structure de répertoires et migration depuis Nuxt 3
Guide complet de migration vers Nuxt 4 : structure de répertoires app/, couche de récupération de données singleton, améliorations TypeScript et instructions de mise à jour pas à pas avec exemples de code.

Nuxt 4 introduit une structure de répertoires repensée qui sépare le code applicatif de la configuration, accompagnée d'une couche de récupération de données singleton, de valeurs par défaut en réactivité superficielle et de contextes TypeScript séparés. Publiée en juillet 2025 et désormais en version 4.4, cette mise à jour majeure privilégie l'évolution plutôt que la révolution, rendant le chemin de migration depuis Nuxt 3 considérablement plus fluide que le passage de Nuxt 2 à 3.
L'équipe Nuxt s'est associée à Codemod pour automatiser la plupart des étapes de migration. Il suffit d'exécuter npx codemod@latest nuxt/4/migration-recipe pour gérer la restructuration des répertoires, les mises à jour de la récupération de données et le remplacement des API dépréciées automatiquement.
La nouvelle structure du répertoire app/ dans Nuxt 4
Nuxt 4 déplace tout le code source de l'application dans un répertoire app/ par défaut. Cette séparation résout un problème concret : les observateurs de fichiers sous Linux et Windows sont nettement plus performants lorsque le code applicatif se trouve dans un sous-répertoire dédié plutôt que mélangé avec node_modules/, .git/ et les fichiers de configuration.
La nouvelle organisation suit cette structure :
my-nuxt-app/
├─ app/
│ ├─ assets/
│ ├─ components/
│ ├─ composables/
│ ├─ layouts/
│ ├─ middleware/
│ ├─ pages/
│ ├─ plugins/
│ ├─ utils/
│ ├─ app.vue
│ ├─ app.config.ts
│ └─ error.vue
├─ content/
├─ public/
├─ shared/ # Nouveau : code partagé entre app et serveur
├─ server/
└─ nuxt.config.tsLe répertoire shared/ constitue un ajout notable. Tout composable ou utilitaire placé dans shared/ devient auto-importé à la fois dans l'application Vue et le serveur Nitro, éliminant la nécessité d'importations manuelles pour partager des schémas de validation, des définitions de types ou des fonctions utilitaires entre les deux contextes.
Migration pas à pas de Nuxt 3 vers Nuxt 4
Le processus de mise à jour commence par une seule commande. Nuxt détecte la structure plate existante et continue de fonctionner sans aucune modification, permettant ainsi une migration incrémentale.
# Mettre à jour Nuxt et dédupliquer les dépendances
npx nuxt upgrade --dedupeAprès la mise à jour du package, il faut déplacer les fichiers applicatifs dans le répertoire app/ :
# Automatiser la restructuration des répertoires
npx codemod@latest nuxt/4/file-structureCe codemod déplace assets/, components/, composables/, layouts/, middleware/, pages/, plugins/, utils/, app.vue, error.vue et app.config.ts dans app/. Les fichiers qui doivent rester à la racine — nuxt.config.ts, server/, public/ et content/ — restent en place.
Pour les projets nécessitant un report de la restructuration, le répertoire source peut être défini explicitement :
export default defineNuxtConfig({
srcDir: '.',
dir: { app: 'app' },
})Cette configuration indique à Nuxt 4 de résoudre les fichiers depuis la racine du projet, reproduisant exactement le comportement de Nuxt 3.
Couche de récupération de données singleton et clés réactives
Nuxt 4 modifie fondamentalement la façon dont useAsyncData et useFetch gèrent les données. Plusieurs composants appelant la même clé partagent désormais une seule référence réactive au lieu de maintenir des copies indépendantes.
export function useProductData(productId: string) {
return useAsyncData(
`product-${productId}`,
() => $fetch(`/api/products/${productId}`),
{
getCachedData: (key, nuxtApp, ctx) => {
// ctx.cause indique la raison du fetch
if (ctx.cause === 'refresh:manual') return undefined
return nuxtApp.payload.data[key]
},
},
)
}Trois changements majeurs caractérisent cette nouvelle couche de données :
- Références partagées : appeler
useProductData('abc')dans deux composants renvoie les mêmes refsdata,erroretstatus. La mise à jour de l'un met à jour l'autre. - Nettoyage automatique : lorsque le dernier composant utilisant une clé est démonté, Nuxt libère les données associées de la mémoire.
- Clés réactives : encapsuler une clé dans un computed ou une ref déclenche automatiquement un nouveau fetch lorsque la valeur change.
Le callback getCachedData reçoit désormais un objet context avec une propriété cause ('initial', 'refresh:hook', 'refresh:manual' ou 'watch'), permettant un contrôle granulaire sur le moment de servir des données en cache plutôt que de récupérer des données fraîches.
Les propriétés data et error de useAsyncData/useFetch ont désormais la valeur par défaut undefined au lieu de null. Il convient de mettre à jour les vérifications === null en === undefined ou d'utiliser une comparaison non stricte.
Réactivité superficielle par défaut pour de meilleures performances
Nuxt 4 bascule data de useAsyncData et useFetch vers shallowRef au lieu de ref. Vue ne suit plus récursivement chaque propriété imbriquée, ce qui apporte des améliorations de performance mesurables pour les réponses d'API contenant des objets profondément imbriqués ou de grands tableaux.
<script setup lang="ts">
// Les données utilisent désormais shallowRef par défaut
const { data: metrics } = await useFetch('/api/dashboard/metrics')
// La mutation directe de propriétés ne déclenche pas la réactivité
// metrics.value.visits = 100 // Ne provoquera pas de re-rendu
// Remplacer la valeur entière pour déclencher les mises à jour
metrics.value = { ...metrics.value, visits: 100 }
// Ou activer la réactivité profonde pour cet appel spécifique
const { data: settings } = await useFetch('/api/settings', {
deep: true,
})
</script>Pour la plupart des affichages en lecture seule (tableaux de bord, listes de produits, pages d'articles), la réactivité superficielle fonctionne sans aucune modification de code. L'option deep: true reste disponible pour les formulaires ou les interfaces interactives qui modifient directement des propriétés imbriquées.
Prêt à réussir tes entretiens Vue.js / Nuxt.js ?
Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.
Séparation des contextes TypeScript et sécurité des types améliorée
Nuxt 4 génère des configurations TypeScript distinctes pour chaque contexte du projet :
.nuxt/tsconfig.app.json— Code de l'application Vue.nuxt/tsconfig.server.json— Code du serveur Nitro.nuxt/tsconfig.shared.json— Utilitaires partagés.nuxt/tsconfig.node.json— Configuration au moment du build
Cette séparation signifie que l'IDE ne suggère plus les API réservées au serveur dans le code client, et inversement. Un seul tsconfig.json à la racine du projet référence les quatre configurations :
{
"files": [],
"references": [
{ "path": "./.nuxt/tsconfig.app.json" },
{ "path": "./.nuxt/tsconfig.server.json" },
{ "path": "./.nuxt/tsconfig.shared.json" },
{ "path": "./.nuxt/tsconfig.node.json" }
]
}La vérification des types en CI change également. La commande vue-tsc nécessite désormais le drapeau -b (mode build) pour traiter correctement les références de projet :
# Avant (Nuxt 3)
nuxt prepare && vue-tsc --noEmit
# Après (Nuxt 4)
nuxt prepare && vue-tsc -b --noEmitAutre modification TypeScript : compilerOptions.noUncheckedIndexedAccess est activé par défaut (true). L'accès à un élément de tableau ou une propriété d'objet par index renvoie désormais T | undefined, capturant les erreurs potentielles à l'exécution dès la compilation.
Noms de composants normalisés et Vue Router v5
Nuxt 4.3 a effectué la mise à niveau vers Vue Router v5, supprimant la dépendance à unplugin-vue-router. Pour la majorité des applications, cette mise à niveau est transparente.
Les conventions de nommage des composants sont désormais standardisées. Un composant situé dans components/dashboard/MetricsCard.vue obtient le nom DashboardMetricsCard de manière cohérente dans tous les contextes — y compris <KeepAlive>, Vue DevTools et les utilitaires de test.
<!-- app/pages/dashboard.vue -->
<template>
<NuxtPage :keepalive="{
include: ['DashboardMetricsCard', 'DashboardRecentActivity'],
}" />
</template>Les projets utilisant <KeepAlive> avec des filtres de noms de composants doivent mettre à jour les noms pour correspondre à cette nouvelle convention. Le comportement précédent, où le nom pouvait varier selon le contexte, ne s'applique plus.
Gestion des changements majeurs dans la gestion du head
Nuxt 4 embarque Unhead v2, qui supprime plusieurs propriétés dépréciées de useHead et useSeoMeta :
<script setup lang="ts">
const route = useRoute()
const { data: product } = await useFetch(`/api/products/${route.params.id}`)
// Unhead v2 : suppression de vmid, hid, children, body
useSeoMeta({
title: () => product.value?.name ?? 'Product',
ogTitle: () => product.value?.name ?? 'Product',
description: () => product.value?.description ?? '',
ogImage: () => product.value?.imageUrl ?? '',
})
</script>Pour les projets s'appuyant sur les paramètres de template ou le tri par alias, ces fonctionnalités doivent être installées comme plugins explicites :
import { TemplateParamsPlugin, AliasSortingPlugin } from '@unhead/vue/plugins'
export default defineNuxtPlugin({
setup() {
const unhead = injectHead()
unhead.use(TemplateParamsPlugin)
unhead.use(AliasSortingPlugin)
},
})Nuxt 3 continue de recevoir des correctifs de sécurité et des corrections de bogues critiques jusqu'au 31 juillet 2026. Après cette date, Nuxt 3 ne sera plus supporté. Planifier la migration dès maintenant évite d'exploiter des applications en production sur un framework en fin de vie.
Checklist de migration et pièges courants
Le codemod automatisé gère la plupart des changements, mais plusieurs éléments nécessitent une attention manuelle :
- Suppression de
window.__NUXT__: remplacer paruseNuxtApp().payload. Cet objet global est supprimé après l'hydratation dans Nuxt 4. - Hook
pages:extend: basculer vers le nouveau hookpages:resolved, qui s'exécute après le scan des méta-données des pages. - Booléen
dedupe: remplacerrefresh({ dedupe: true })parrefresh({ dedupe: 'cancel' })etfalsepar'defer'. - Styles inline : seuls les styles des composants Vue sont inlinés par défaut ; le CSS global est chargé sous forme de fichiers séparés. Ajouter
features: { inlineStyles: true }pour restaurer le comportement de Nuxt 3. clearNuxtState: réinitialise désormais aux valeurs initiales au lieu deundefined. UtiliserclearNuxtState('key', { reset: false })pour retrouver l'ancien comportement.
Une séquence de migration pratique pour les applications en production :
- Exécuter
npx nuxt upgrade --dedupeet vérifier que l'application se build correctement - Lancer le codemod :
npx codemod@latest nuxt/4/migration-recipe - Déplacer les fichiers dans
app/(automatisé par le codemod file-structure) - Mettre à jour les vérifications
nullenundefineddans la logique de récupération de données - Tester les composants
<KeepAlive>avec les noms normalisés - Mettre à jour la vérification des types en CI pour utiliser
vue-tsc -b --noEmit - Lancer la suite de tests complète et corriger les erreurs TypeScript révélées par
noUncheckedIndexedAccess
Pour approfondir les concepts Vue et Nuxt, il est possible d'explorer les questions d'entretien Vue/Nuxt sur SharpSkill, ou de consulter le guide SSR et génération statique pour des informations sur les stratégies de rendu qui s'appliquent également à Nuxt 4.
Conclusion
- Nuxt 4.4 (version actuelle en avril 2026) stabilise la structure du répertoire
app/, la récupération de données singleton et les contextes TypeScript séparés comme valeurs par défaut prêtes pour la production - La commande
npx codemod@latest nuxt/4/migration-recipeautomatise la restructuration des répertoires, le remplacement des API dépréciées et les mises à jour de la récupération de données - La réactivité superficielle via
shallowRefaméliore les performances des pages en lecture intensive sans nécessiter de modifications de code dans la plupart des cas - Les configurations TypeScript séparées par contexte (app, server, shared, node) éliminent les fuites de types inter-contextes et améliorent l'autocomplétion de l'IDE
- Nuxt 3 atteint sa fin de vie le 31 juillet 2026 — migrer avant cette date garantit le fonctionnement des applications sur une version supportée et activement maintenue
- Vue Router v5 et Unhead v2 apportent des API plus propres au prix de la suppression de propriétés dépréciées qui doivent être auditées lors de la migration
Tags
Partager
Articles similaires

Vue 3 Pinia vs Vuex : Gestion d'État Moderne et Questions d'Entretien 2026
Comparaison approfondie entre Pinia et Vuex : architecture, TypeScript, Composition API, performances, stratégies de migration et questions d'entretien Vue fréquentes en 2026.

Nuxt 3 : SSR et génération statique, le guide complet
Maîtrisez le SSR et la génération statique avec Nuxt 3. De useFetch à generateRoutes, découvrez comment optimiser les performances de vos applications Vue.

Questions d'entretien Vue.js essentielles : 25 questions pour réussir
Préparez vos entretiens Vue.js avec ces 25 questions essentielles. De la réactivité aux composables, maîtrisez les concepts clés pour décrocher le poste.