Working with layers in Nuxt 3
Introduction
In this short article I would like to talk about such a concept as Layers in Nuxt 3, how I implement it in my projects and why I think it is important. I will show two examples: one demonstrates dividing a project into several layers, and the other – dividing several frontends into different layers. The desire to write an article about this arose after I did not find a sufficient number of real examples and articles in Russian on the use of layers.
The problem that brought me to Layers
Initially, I knew about the Layers concept in Nuxt 3, but I didn’t use it, considering it unnecessary and not very clear. But one day, when I found myself digging through a folder components
which had at least six subfolders, each with 10-30 components, I realized that something was clearly wrong. I decided to split my project into several layers, but in such a way as to avoid one layer depending on another. After some time, I came up with the following structure:
Base: This layer contains the general components of the site, such as the header, footer, layouts, composables and utilities used throughout the project, as well as the main page, user agreement page, etc.
User: The layer responsible for working with authorization, user profile and everything that directly concerns the user.
Order: Everything related to orders on the site: the order creation page, the list of user orders, the list of all orders on the site, etc.
Chat: Chat page between users. The logic of working with the web socket is also implemented on this layer.
UI: Due to the growing Base layer, it was decided to move all UI components to a separate layer. It is needed so that 20 components related to forms, modal windows and cards do not clutter the base layer, which contains more global parts and pages of the application.
The main advantages I have felt when using this approach are, firstly, the convenience of working on a specific part of the application. If I need to update authorization, I do not search for components/pages/composables throughout the project, but go to a specific layer and work exclusively in it, without affecting the rest. Secondly, each layer can be assigned its own configuration.
Project structure:
├── layers/
│ ├── base/
│ │ ├── assets/
│ │ │ ├── fonts/
│ │ │ └── styles/
│ │ ├── components/
│ │ ├── composables/
│ │ ├── pages/
│ │ ├── stores/
│ │ ├── utils/
│ │ └── nuxt.config.ts
│ ├── chat/
│ │ ├── components/
│ │ ├── composables/
│ │ ├── pages/
│ │ ├── stores/
│ │ └── nuxt.config.ts
│ ├── order/
│ │ ├── components/
│ │ ├── pages/
│ │ ├── stores/
│ │ ├── specialist/
│ │ └── support/
│ ├── ui/
│ │ ├── components/
│ │ └── nuxt.config.ts
│ └── user/
│ ├── components/
│ ├── composables/
│ ├── middleware/
│ ├── pages/
│ ├── stores/
│ └── nuxt.config.ts
├── app.vue
├── error.vue
├── nuxt.config.ts
└── tsconfig.json
In the main nuxt.config.ts
I have the following written in the file:
extends: [
"./layers/base",
"./layers/ui",
"./layers/order",
"./layers/user",
"./layers/chat"
],
// Исключительно для удобства при импортировании
alias: {
"@": "./",
base: "~/layers/base",
ui: "~/layers/ui",
order: "~/layers/order",
user: "~/layers/user",
chat: "~/layers/chat",
}
The problem I encountered
If two different layers have a component with the same name, only one will be auto-imported. This creates the risk of accidentally naming a component exactly the same as in another layer, and not understanding why everything is not working correctly. In an attempt to find a solution to the problem, I decided to disable auto-import in all layers, but in order not to lose the advantage of using auto-import, I made in each layer inside the folder components
folder global
. From it, all components are available for auto-import throughout the application, and components outside of this folder must be imported directly. To implement such logic in each internal nuxt.config.ts
you need to write the following:
components: [
{
path: "~/layers/base/components/global",
pathPrefix: false,
global: true
}
]
Multiple sites based on one API
Our team was faced with the task of creating several sites that would access one API, have common components, composables and utilities. We decided to implement this through Layers, where each layer is a separate site.
The structure is as follows:
├── composables/
├── components/
├── services/
├── layers/
│ ├── site-1/
│ ├── site-2/
│ └── site-3/
IN .env
the file contains a parameter that is responsible for the current site, for example VITE_NUXT_LAYER=site-1
. It is needed in order to nuxt.config.ts
specify the path to the required site:
extends: ["./layers/" + import.meta.env.VITE_NUXT_LAYER]
After this, each developer writes down the name of the site he needs and works exclusively within one layer, without affecting the work of others.
Conclusion
Using Layers in Nuxt 3 allows you to significantly improve the structure and manageability of large projects. Separation into layers helps to avoid unnecessary dependencies and makes it easier to work on individual parts of the application.
useful links
Documentation Layers Nuxt