Project Structure & Conventions
The directories Nuxt treats specially, and why putting a file in the right folder is most of the configuration you need.
읽는 데 2분
Nuxt is convention-driven: instead of registering routes, components, or composables in a config file, you put them in a specific directory and Nuxt picks them up automatically. Knowing what each top-level folder means is most of what you need to navigate — and build — a Nuxt project.
The directories that matter most
my-nuxt-app/
├─ app.vue # root component
├─ pages/ # file-based routes
├─ components/ # auto-imported Vue components
├─ composables/ # auto-imported composable functions
├─ layouts/ # shared page shells (header/footer, etc.)
├─ middleware/ # route guards, run before navigation
├─ plugins/ # code that runs once on app startup
├─ server/ # backend API routes and server middleware (Nitro)
├─ public/ # static files served as-is (favicon, robots.txt)
├─ assets/ # images/CSS that go through the build pipeline
└─ nuxt.config.ts # framework configuration
Every one of these is optional — a folder that doesn't exist is simply skipped — but each one has a well-defined job. That's different from a plain Vite project, where src/ is just "wherever you put things," and where they go is a team convention rather than something the framework understands.
Why the convention matters more than it looks
Consider components/. In a plain Vue app, using a component means importing it:
<script setup>
import BaseButton from "~/components/BaseButton.vue";
</script>
<template>
<BaseButton>Save</BaseButton>
</template>In Nuxt, dropping BaseButton.vue into components/ is enough — no import needed (covered in depth in the auto-imports lesson):
<script setup>
// nothing to import — BaseButton is already available
</script>
<template>
<BaseButton>Save</BaseButton>
</template>This works because Nuxt scans these folders at build time and generates the imports for you behind the scenes. The convention isn't just "less typing" — it means every Nuxt project has the same answer to "where does this file go," which is a real advantage when you join an existing codebase.
Nested folders keep meaning
Subfolders inside these directories are meaningful too. components/base/Button.vue becomes <BaseButton /> (the folder name is prefixed), and pages/blog/[slug].vue becomes the route /blog/:slug — covered next. The takeaway for this lesson: in Nuxt, file location is configuration. Before reaching for a config option, check whether there's already a folder convention that does the job.