Provide clarification for nuxt 4 directory structure
I don't quite understand the directory structure. More specifically, how are the plugins, and modules folders shared betwee app and server? If I want to create a new custom module that works on both app and server side, should I create a shared folder, then a modules folder? It would be easier to just have a root level modules folder.
5 Replies
Hi @Thick Black W. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Certainly! Here’s a clarification of the Nuxt 4 directory structure, focusing on the roles of the
- Use
plugins
, modules
, and shared
folders, and how to structure a custom module that works on both the app and server sides.
---
Nuxt 4 Directory Structure Overview
In Nuxt 4, the default structure is:
- app/
contains all your client-side (Vue app) code.
- server/
contains server-side code (API routes, middleware, Nitro plugins, etc.).
- modules/
is for local Nuxt modules (these can register code for both app and server).
- shared/
is for code (like utilities and types) that needs to be used in both the app and server contexts, but cannot import Vue or Nitro-specific code Docs: shared.
---
Plugins
- app/plugins/
is for Nuxt plugins that run in the Vue app context. You can use .server
or .client
suffixes to restrict plugins to server or client only, but these are still Vue app plugins, not Nitro/server plugins Docs: plugins.
- server/plugins/
is for Nitro plugins, which extend the server runtime (Nitro) and are not available in the Vue app context Docs: server.
They are not shared between app and server. Each context has its own plugin system.
---
Modules
- The root-level modules/
folder is for local Nuxt modules. These modules can register code for both the app and server sides, depending on how you implement them. You do not need to create separate modules
folders for app and server—just use the root-level one Docs: modules.
- Modules can inject plugins, add server handlers, and more, so they are the right place for code that needs to affect both sides.
---
Shared Folder
- The shared/
folder is for utilities and types that need to be used in both the app and server, but cannot import Vue or Nitro code. Only shared/utils/
and shared/types/
are auto-imported; other files must be imported manually using the #shared
alias Docs: shared.
- Use this for pure JavaScript/TypeScript code that is context-agnostic.
---
Creating a Custom Module for Both App and Server
- Use the root-level modules/
folder. Your module can register plugins for the app, add server handlers, and more.
- If you need to share utility code between app and server, put that code in shared/
and import it in your module or plugins as needed.
You do not need to create a modules
folder inside shared/
or vice versa. The root-level modules/
is the standard and recommended approach.
---
#### Example Structure
---
Summary:- Use
modules/
at the root for custom modules that affect both app and server.
- Use shared/
for utilities/types needed in both contexts.
- Plugins are context-specific: app/plugins/
for Vue app, server/plugins/
for Nitro/server.
For more details, see the Nuxt 4 Upgrade Guide and Directory Structure documentation.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@1321238874634195004> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
And where do you put the <i18n> folder?
In the app/i18n/locales/en/main.json folder or in the root i18n/locales/en/main.json ?
The modules folder should be located at the root of your project
I prefer app folder: In the app/i18n/locales/en/main.json