10 juillet 2026 · Nuxt · Architecture

Comprendre l'architecture de Nuxt 4 : la carte du framework

Dossiers, auto-imports, routing, modes de rendu, Nitro : une vue d'ensemble structurée de Nuxt 4 pour savoir où va chaque chose et pourquoi.

Quand on arrive sur Nuxt en venant de Vue « nu », la première impression est déroutante : beaucoup de choses semblent se produire toutes seules. Les composants s'importent sans qu'on les importe, une page apparaît dès qu'on crée un fichier, une fonction serveur devient une URL. Ce n'est pas de la magie, c'est une convention. Une fois la carte du framework en tête, Nuxt devient très prévisible. Voici cette carte.

La structure de dossiers

En Nuxt 4, le code applicatif vit dans app/, et le reste du projet s'organise autour. Chaque dossier a un rôle précis et une convention associée :

  • app/pages/ : chaque fichier .vue devient une route. C'est le routing par fichiers (voir plus bas).
  • app/components/ : les composants réutilisables, auto-importés dans tout le projet.
  • app/composables/ : la logique réactive réutilisable, elle aussi auto-importée.
  • app/layouts/ : les gabarits qui enveloppent les pages (en-tête, pied de page, structure commune).
  • app/plugins/ : le code qui s'exécute à l'initialisation de l'application, côté client, serveur ou les deux.
  • app/middleware/ : les gardes de navigation, exécutés avant d'entrer sur une route (redirections, contrôle d'accès).
  • app/assets/ : les ressources traitées par le build (CSS, images optimisées, polices).
  • server/ : le code serveur, à la racine du projet et non dans app/, car il ne tourne jamais dans le navigateur.
  • public/ : les fichiers servis tels quels, sans transformation (favicon, robots.txt, images fixes).
  • nuxt.config.ts : le point de contrôle unique de toute la configuration.

La règle mentale est simple : le nom du dossier décrit son rôle, et le rôle impose la convention. Vous ne choisissez pas où mettre un composable, vous le posez dans composables/ et Nuxt fait le reste.

Les auto-imports

C'est la fonctionnalité qui déroute le plus au début. Les composants de components/, les fonctions de composables/ et utils/, ainsi que les utilitaires du framework (ref, computed, useRoute, useFetch) sont disponibles partout sans ligne d'import.

<script setup lang="ts">
// Aucun import : ref, useRoute et MonComposant sont auto-importés
const route = useRoute()
const compteur = ref(0)
</script>

<template>
  <MonComposant :id="route.params.id" @clic="compteur++" />
</template>

Ce n'est pas de la magie opaque : Nuxt génère des déclarations de types dans .nuxt/ pour que l'éditeur et TypeScript connaissent ces symboles. Le bénéfice est un code débarrassé de vingt lignes d'imports en haut de chaque fichier ; le prix est qu'il faut connaître la convention pour savoir d'où vient une fonction. La règle : si vous ne voyez pas l'import, cherchez dans composables/, components/ ou la documentation des use* de Nuxt.

Le routing par fichiers

Il n'y a pas de fichier de routes à maintenir. L'arborescence de app/pages/ est la table de routage :

  • pages/index.vue donne /
  • pages/blog/index.vue donne /blog
  • pages/blog/[slug].vue donne /blog/mon-article (segment dynamique)
  • pages/projets/[slug].vue donne /projets/nom-du-projet

Le paramètre dynamique se lit avec useRoute().params.slug. Ajouter une page, c'est ajouter un fichier ; supprimer une page, c'est supprimer un fichier. Le routeur suit toujours le disque.

Les modes de rendu

C'est la décision d'architecture la plus structurante, et Nuxt la rend souple. Le même code peut être servi de plusieurs façons :

  • SSR (rendu serveur) : le HTML est généré à la demande sur le serveur, puis hydraté côté client. Idéal pour du contenu dynamique et le SEO.
  • SSG (génération statique, nuxi generate) : tout le site est pré-rendu en HTML au build, puis servi comme des fichiers. Idéal pour un site vitrine ou un blog. C'est le mode de ce site.
  • SPA : rendu uniquement côté client, pour une application derrière une authentification où le SEO n'importe pas.
  • Hybride : via routeRules dans nuxt.config, on choisit le mode route par route (une partie statique, une partie serveur, une partie en cache).
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },          // page d'accueil figée au build
    '/blog/**': { prerender: true },   // articles statiques
    '/api/**': { cors: true },         // routes serveur dynamiques
    '/admin/**': { ssr: false }        // espace privé en SPA
  }
})

Ne choisissez pas le mode par habitude : choisissez-le par besoin réel de chaque partie du site.

Nitro : le serveur universel

Sous Nuxt, il y a Nitro, le moteur serveur. C'est lui qui exécute le SSR, qui sert le dossier server/, et surtout qui permet de déployer le même projet sur des cibles très différentes (Node, un hébergeur statique, un worker edge) sans changer le code. Quand vous écrivez une route dans server/api/, c'est Nitro qui la transforme en point d'accès HTTP. J'y reviens en détail dans l'article sur les applications fullstack.

Les modules

Un module Nuxt est une extension qui s'installe et se configure en une ligne, et qui apporte ses propres conventions. Ce site en utilise plusieurs : @nuxt/content pour écrire les articles en Markdown, @nuxtjs/i18n pour le bilinguisme, @nuxtjs/seo pour les métadonnées et le sitemap. Un bon réflexe avant de coder une fonctionnalité transverse : vérifier s'il existe déjà un module qui la fournit avec ses conventions éprouvées.

La leçon

Nuxt n'est pas Vue « avec des trucs en plus » : c'est un cadre de conventions qui répond à une seule question, « où va chaque chose ». Une fois la carte assimilée (un dossier par rôle, l'auto-import, le routing par fichiers, le mode de rendu choisi par besoin, Nitro derrière), le framework cesse de surprendre et devient un accélérateur. Le temps passé à comprendre cette structure au départ est remboursé sur chaque fonctionnalité ensuite.

← Tous les articles