Com estructurar un projecte Nuxt gran sense perdre el control
Quan Nuxt creix, la clau no és afegir carpetes: és definir convencions, límits de responsabilitat i fluxos de qualitat que l'equip pugui seguir sense pensar.
Per Alex Romero

Nuxt.js és excel·lent per a projectes petits i mitjans gràcies a la seva convenció sobre configuració. Però quan un projecte creix —més pàgines, més composables, més integracions externes, més membres a l'equip— les convencions per defecte es queden curtes. Sense una arquitectura deliberada, el codi s'acumula en `components/` i `composables/` sense estructura, les pàgines comencen a tenir lògica de negoci, i cada nou desenvolupador tarda dies a entendre com funciona el projecte.
El principi fonamental: separació de responsabilitats
La majoria de problemes d'arquitectura en projectes Nuxt grans vénen de la mateixa causa: mesclar responsabilitats a la mateixa capa. Una pàgina que fa una crida a l'API, transforma les dades, gestiona l'estat local i renderitza el markup és impossible de mantenir i testar.
La separació correcta segueix tres capes. La capa de presentació (components/ i pages/) només es preocupa de com es veu i com interactua l'usuari. No té lògica de negoci —crida composables i renderitza el que rep. La capa d'aplicació (composables/) conté la lògica de negoci: gestió d'estat, transformació de dades, validació. No crida APIs directament —usa la capa de dades. La capa de dades (server/api/ o utils/api/) gestiona totes les comunicacions externes: APIs REST, bases de dades, CMS. Retorna dades normalitzades que la capa d'aplicació pot usar directament.
- Organitza per domini, no per tipus de fitxer: en lloc de components/forms/, components/cards/, components/modals/, usa components/users/, components/products/, components/checkout/. Cada carpeta de domini conté tots els components, composables i utils relacionats.
- Composables orientats a casos d'ús: useProductSearch() i useCartActions() en lloc de useApi() i useState(). El nom ha de descriure el que fa, no com ho fa.
- Centralitza clients API: crea un fitxer utils/api/client.ts que encapsuli la configuració de $fetch (headers d'autenticació, interceptors, gestió d'errors). Mai creis $fetch directament des d'un composable o component.
- Patrons de naming consistents: usa PascalCase per a components (UserCard.vue), camelCase per a composables (useUserData.ts), kebab-case per a pàgines i routes (/user-profile). Documenta les convencions en un CONVENTIONS.md al root.
- Gestió d'errors centralitzada: crea un composable useError() que gestioni tots els estats d'error de manera uniforme. Evita cada component gestionant els seus propis errors de manera inconsistent.
- Server routes per a lògica sensible: tota la lògica que implica claus d'API, accés a bases de dades o transformacions complexes ha d'anar a server/api/, no al client. Nuxt server routes s'executen al servidor i no exposen lògica sensible al navegador.
- Tests de regressió en punts crítics: no cal testar-ho tot, però els composables amb lògica de negoci important (càlculs de preu, validació de formularis, transformació de dades) han de tenir tests unitaris. Usa Vitest, que s'integra perfectament amb Nuxt.
- Documenta decisions tècniques: usa ADRs (Architecture Decision Records) en una carpeta docs/decisions/. Cada decisió important (per què usem Pinia i no useState, per què vam triar Stripe i no Redsys) ha de tenir un fitxer Markdown que expliqui el context, les alternatives considerades i la decisió presa.
Estructura recomanada per a projectes Nuxt de mida mitjana-gran
Una estructura que funciona bé per a projectes de 5-15 desarrolladors: `/app` per a tot el codi del client (pages, components, composables, organitzats per domini), `/server` per a totes les API routes i middleware de servidor, `/shared` per a tipus TypeScript, constants i utils pures que es comparteixen entre client i servidor, i `/docs` per a ADRs i documentació tècnica.
La clau no és la carpeta —és la consistència. Una estructura simple aplicada de manera consistent és infinitament millor que una arquitectura perfecta que l'equip no segueix. Defineix les convencions, escriu-les, revisa-les en code review i actualitza-les quan canvien les necessitats.
Una arquitectura simple i consistent redueix fricció, onboarding i errors en cada entrega. El millor moment per definir-la és quan el projecte comença; el segon millor moment és ara.