---
title: "Understanding the Project Structure"
description: "A complete, beginner-friendly tour of the Nuxas project structure. Learn what each folder does and where to find the files you will edit most often."
canonical_url: "https://nuxas.pages.dev/docs/06-structure"
---

> Index of every page on this site: [llms.txt](https://nuxas.pages.dev/llms.txt)

## Understanding the Project Structure

In the previous chapter, we configured the project for your own domain and created the `.env` file. Now it is time to take a tour of the project structure.

This chapter is shorter than the others, but it is important. Knowing where files live will save you hours of searching later. You do not need to memorize everything — just keep this chapter nearby as a reference.

### The Big Picture

When you open the project in VS Code, you will see something like this in the file explorer:

```text
my-project/
├── app/
├── content/
├── data/
├── public/
├── server/
├── shared/
├── nuxt.config.ts
├── content.config.ts
├── package.json
├── tsconfig.json
└── .env
```

Let us go through each one, from most important to least important.

### The `app` Folder

This is where most of your code lives. It contains the pages, components, composables, layouts, and plugins of your application.

Inside `app`, you will find:

- **app.vue** — the root component of your application. It is small; it just wraps the layout and the page.
- **assets/** — CSS files, fonts, and images that are processed by the build system. Most of your styling lives in `assets/css/main.css`.
- **components/** — reusable Vue components. They are organized into subfolders like `layout/`, `ui/`, `product/`, and `blog/`.
- **composables/** — reusable Vue composables. These are functions that return reactive state. For example, `useTheme` manages dark mode, and `useMobileNav` manages the mobile drawer.
- **layouts/** — layout files. The `default.vue` layout wraps every page with the header and footer. The `docs.vue` layout is used specifically for documentation pages.
- **pages/** — the pages of your application. Each file in this folder becomes a route. For example, `pages/index.vue` becomes the homepage, and `pages/products/index.vue` becomes the products page.
- **plugins/** — plugins that run before the app starts. For example, `theme.client.ts` sets up the initial theme.

Most of your work will happen in `pages/` and `components/`.

### The `content` Folder

This folder holds your content. It is managed by Nuxt Content, a module that reads Markdown and YAML files and makes them queryable from your Vue code.

Inside `content`, you will find:

- **blog/** — blog posts, one Markdown file per post.
- **products/** — product pages, one Markdown file per product.
- **pages/** — static pages like About, Privacy, or Terms.
- **contact.md** — the contact page content.
- **404.md** — the 404 error page content.
- **data/** — configuration files in YAML format. This is where `site.yml`, `product.yml`, `blog.yml`, and `docs.yml` live.

If you are using the Code Only edition, you will edit these files directly. If you are using the Decap CMS edition, you will edit them through the CMS dashboard, and the files will be updated automatically.

### The `public` Folder

Files in this folder are served as-is, without any processing. This is where you put things like:

- `favicon.ico` — the small icon that appears in the browser tab.
- `robots.txt` — the file that tells search engines which pages to index.
- `admin/` — the Decap CMS admin interface. This folder exists only in the CMS edition.
- `uploads/` — images uploaded through Decap CMS.

Files in `public` are accessed from the root URL. For example, `public/favicon.ico` is accessible at `https://your-domain.com/favicon.ico`.

### The `server` Folder

This folder contains the backend code of your application. Nuxt 4 uses Nitro, a server engine that compiles your backend into a portable server that runs on any hosting provider.

Inside `server`, you will find:

- **api/** — API endpoints. Each file becomes an API route. For example, `api/contact.post.ts` handles contact form submissions.

If you are not adding custom backend logic, you will rarely edit files in this folder.

### The `shared` Folder

This folder contains TypeScript types that are shared between the client and the server. For example, `shared/types/product.ts` defines the `Product` interface, which is used in both the frontend and the backend.

If you add a new field to a product, you will need to update the type in this folder.

### The Root Files

At the root of the project, you will find a few important files:

- **nuxt.config.ts** — the main configuration file. You already edited this in the previous chapter.
- **content.config.ts** — the configuration for Nuxt Content. It defines the shape of each content collection (blog, products, pages, etc.).
- **package.json** — lists the project's dependencies and scripts. You will use `npm run dev` and `npm run build` from this file.
- **tsconfig.json** — the TypeScript configuration. You rarely need to edit this.
- **.env** — the environment variables file. You created this in the previous chapter.

### How Nuxt Generates Routes

One of the most magical things about Nuxt is how it generates routes from files. Here is how it works:

- `app/pages/index.vue` → `/`
- `app/pages/about.vue` → `/about`
- `app/pages/products/index.vue` → `/products`
- `app/pages/products/[slug].vue` → `/products/:slug` (dynamic route)
- `app/pages/blog/[slug].vue` → `/blog/:slug`
- `app/pages/docs/[slug].vue` → `/docs/:slug`

You do not need to configure a router manually. Nuxt reads the folder structure and generates routes automatically.

### How Nuxt Content Works

Nuxt Content is what connects the `content` folder to your Vue code. Each file in `content/blog/` becomes a blog post. Each file in `content/products/` becomes a product. The `content/data/` folder holds configuration files that are queried from your code.

The `content.config.ts` file defines the shape of each collection. For example, it says "every blog post must have a title, a description, a date, and a body." If a blog post is missing one of these fields, Nuxt Content will refuse to load it, and you will see an error.

This is why it is important to keep `content.config.ts` in sync with your content files. If you add a new field to a blog post, you also need to add it to `content.config.ts`.

### What to Expect in the Next Chapter

In the next chapter, we will run Nuxas with Decap CMS. This chapter is only relevant if you purchased the Code + Decap CMS edition. If you purchased the Code Only edition, you can skip it and continue to the chapter after next.

We will show you how to run the site and the CMS side by side, using two terminals. See you there.

## Sitemap

See the full [sitemap](https://nuxas.pages.dev/sitemap.md) for all pages.
