Installation and Project Structure
Alice wants to run MegaShop locally but is confused by Nuxt 3's directory conventions—if files are placed in the wrong location, components won't be automatically imported. Bob's project has a messy configuration, causing problems with every build. Charlie needs a clear directory structure to standardize the team's development.
1. What You'll Learn
- npx nuxi@latest init: Create a project and select a package manager
- Core directory conventions: pages/components/composables/server, etc.
- A Detailed Explanation of nuxt.config.ts
- How auto-imports Work
- Hands-On Guide to Initializing the MegaShop Project
2. A Developer's True Story
(1) Pain Point: A disorganized directory structure causes components to "disappear"
Alice placed ProductCard.vue under src/components/shop/, which resulted in an error on the page: "Component ProductCard is not found." She wasn't aware of Nuxt 3's directory conventions—the component path determines the component name. components/shop/ProductCard.vue should be referenced as `<ShopProductCard />`. This implicit rule often trips up beginners.
(2) A Solution for the Nuxt 3 Directory Convention
Nuxt 3 uses directory conventions instead of manual configuration—files are automatically available when placed in the correct directory, with no need for import statements. Once she understands the conventions, Alice simply needs to organize her files according to the rules:
components/
ProductCard.vue → <ProductCard />
shop/
ProductList.vue → <ShopProductList />
(3) Benefits: Doubling Development Efficiency
Once the team understood the directory conventions, Alice's components no longer "disappeared," and the time it took for new team members to get up to speed was reduced from 2 days to 4 hours.
3. Creating a Nuxt 3 Project
(1) Initialization Command
# Create new Nuxt 3 project
npx nuxi@latest init megashop
# Or with specific package manager
npx nuxi@latest init megashop --packageManager pnpm
(2) Package Manager Comparison
| Dimension | npm | pnpm | yarn |
|---|---|---|---|
| Installation Speed | 🐢 Slow | ⚡ Fastest | ⚡ Fast |
| Disk Usage | 🔴 High | 🟢 Low (hard links) | 🟡 Medium |
| Monorepo | ⚠️ Requires workspaces | ✅ Native support | ✅ Supported |
| Rating | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
(1) ▶ Example: Initialization and Startup
# Step 1: Create project
npx nuxi@latest init megashop
# Step 2: Enter project directory
cd megashop
# Step 3: Install dependencies
npm install
# Step 4: Start dev server
npm run dev
# → Nuxt dev server running at http://localhost:3000
Output:
# Command executed successfully
(2) ▶ Example: Core scripts in package.json
{
"name": "megashop",
"private": true,
"scripts": {
"build": "nuxi build",
"dev": "nuxi dev",
"generate": "nuxi generate",
"preview": "nuxi preview",
"postinstall": "nuxi prepare"
},
"dependencies": {
"nuxt": "^3.12.0"
},
"devDependencies": {
"@nuxt/devtools": "latest"
}
}
Output:
{
"name": "megashop",
"private": true,
"scripts": {
"build": "nuxi build",
"dev": "nuxi dev",
"generate": "nuxi generate",
"preview": "nuxi preview",
"postinstall": "nuxi prepare"
},
"dependencies": {
"nuxt": "^3.12.0"
},
"devDependencies": {
"@nuxt/devtools": "latest"
}
}
4. Core Directory Conventions
(1) Overview of the Directory Structure
graph TB
A[megashop/] --> B[pages/ → Routes]
A --> C[components/ → Auto-import Components]
A --> D[composables/ → Auto-import Functions]
A --> E[server/ → API Routes]
A --> F[layouts/ → Page Layouts]
A --> G[plugins/ → Auto-register Plugins]
A --> H[middleware/ → Route Guards]
A --> I[assets/ → Processed by Build]
A --> J[public/ → Static Files]
A --> K[nuxt.config.ts → Project Config]
A --> L[app.vue → Root Component]
(2) Responsibilities and Rules for Each Directory
| Table of Contents | Responsibilities | Automatic Registration | Uses of MegaShop |
|---|---|---|---|
| pages/ | Route Pages | ✅ Auto-Generate Routes | Product Pages/Category Pages/Home Page |
| components/ | Vue component | ✅ Auto-import | ProductCard/Header/Footer |
| composables/ | composable functions | ✅ Auto-import | useCart/useProduct |
| server/api/ | API Routes | ✅ Auto-registration | /api/products /api/cart |
| server/middleware/ | Server-side middleware | ✅ Applies globally | auth/CORS |
| layouts/ | Page Layout | ✅ Auto-Registration | default/sidebar |
| plugins/ | Plugins | ✅ Automated | stripe/payment |
| middleware/ | Routing middleware | ✅ Can be referenced | auth/admin |
| assets/ | Build and process resources | ❌ Requires a reference | CSS/Fonts/SCSS |
| public/ | Static files | ❌ Direct access | favicon/robots.txt |
(1) ▶ Example: MegaShop Directory Structure
megashop/
├── app.vue # Root component
├── nuxt.config.ts # Project config
├── pages/
│ ├── index.vue # Homepage
│ ├── products/
│ │ ├── index.vue # Product list
│ │ └── [id].vue # Product detail
│ ├── categories/
│ │ └── [slug].vue # Category page
│ ├── cart.vue # Shopping cart
│ └── about.vue # About page
├── components/
│ ├── AppHeader.vue # → <AppHeader />
│ ├── AppFooter.vue # → <AppFooter />
│ └── product/
│ ├── ProductCard.vue # → <ProductProductCard /> ①
│ └── ProductList.vue # → <ProductProductList /> ①
├── composables/
│ ├── useCart.ts # → auto-imported
│ └── usePriceFormat.ts # → auto-imported
├── server/
│ └── api/
│ ├── products/
│ │ └── index.get.ts # GET /api/products
│ └── cart/
│ └── index.post.ts # POST /api/cart
├── layouts/
│ ├── default.vue # Default layout
│ └── sidebar.vue # Sidebar layout
├── middleware/
│ └── auth.ts # Named middleware
├── plugins/
│ └── stripe.client.ts # Client-only plugin
├── assets/
│ └── css/
│ └── main.css # Global styles
└── public/
├── favicon.ico
└── robots.txt
Output:
Execution Successful
components/product/ProductCard.vue is Product, i.e., <ProductProductCard />. You can disable the prefix by configuring pathPrefix in nuxt.config.ts.
5. Detailed Explanation of nuxt.config.ts
(1) Core Configuration Options
| Option | Type | Description | MegaShop Example |
|---|---|---|---|
| ssr | boolean | Global SSR Toggle | true |
| modules | array | Module List | @pinia/nuxt |
| runtimeConfig | object | Runtime Configuration | API Key/Database URL |
| app | object | app metadata | head/title/templateId |
| vite | object | Vite Configuration | Proxies/Plugins |
| routeRules | object | Route-level rendering policy | ISR/CSR/Cache |
| components | object | Component Import Configuration | Prefix/Scan Path |
(1) ▶ Example: MegaShop Basic Configuration
// nuxt.config.ts
export default defineNuxtConfig({
// Global SSR setting
ssr: true,
// App metadata
app: {
head: {
title: 'MegaShop - Premium E-Commerce',
meta: [
{ name: 'description', content: 'Millions of products, shipped worldwide' }
]
}
},
// Runtime config (server-only secrets)
runtimeConfig: {
// Private - server only
databaseUrl: process.env.DATABASE_URL,
stripeSecretKey: process.env.STRIPE_SECRET_KEY,
// Public - exposed to client
public: {
apiBase: process.env.API_BASE || 'http://localhost:3000/api',
stripePublishableKey: process.env.STRIPE_PUBLISHABLE_KEY
}
},
// Modules
modules: [
'@pinia/nuxt',
'@nuxtjs/tailwindcss'
],
// Component path prefix setting
components: [
{ path: '~/components', pathPrefix: false }
]
})
Output:
// Execution Successful
(2) ▶ Example: routeRules Rendering Strategy
// nuxt.config.ts - route-level rendering rules
export default defineNuxtConfig({
routeRules: {
// Homepage: pre-render at build time
'/': { prerender: true },
// Product list: ISR with 60s revalidation
'/products': { swr: 60 },
// Product detail: ISR with 3600s revalidation
'/products/**': { swr: 3600 },
// Admin dashboard: client-side only
'/admin/**': { ssr: false },
// API: CORS headers
'/api/**': { cors: true }
}
})
Output:
// Execution Successful
6. How the Auto-imports Mechanism Works
(1) Automatic Registration Process
flowchart LR
A[Nuxt Scan Directories] --> B[Generate .nuxt/imports.d.ts]
B --> C[Generate .nuxt/components.d.ts]
C --> D[TypeScript Auto-complete]
A --> E[Generate .nuxt/routes.ts]
E --> F[Vue Router Config]
(2) Automatic Import Range
| Type | Directory | Prefix Rule | Example |
|---|---|---|---|
| Component | components/ | Directory path prefix | ProductCard → <ProductCard /> |
| Composable | composables/ | use prefix | useCart() → auto-imported |
| Utility Functions | utils/ | No prefix | formatPrice() → auto-imported |
| Built-in APIs | Nuxt 3 Core | "use" prefix | useFetch/useState/useRouter |
(1) ▶ Example: Automatic Import of Composables
// composables/usePriceFormat.ts
// No need to import - auto-imported by Nuxt
export function usePriceFormat(price: number, currency: string = 'USD'): string {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency
}).format(price)
}
// In any component - use directly
// const formatted = usePriceFormat(2999.99) → "$2,999.99"
Output:
// Execution Successful
(2) ▶ Example: Automatic Import Validation for Components
<!-- pages/index.vue -->
<template>
<!-- All components auto-imported, no import statement needed -->
<div>
<AppHeader />
<ProductCard :product="featured" />
<AppFooter />
</div>
</template>
<script setup lang="ts">
// All composables auto-imported
const { data: featured } = await useFetch('/api/products/featured')
const price = usePriceFormat(featured.value?.price || 0)
</script>
Output:
// Execution Successful
7. Comprehensive Example: Initializing the MegaShop Project
# ============================================
# MegaShop Project Initialization
# Complete setup from zero to running dev server
# ============================================
# 1. Create project
npx nuxi@latest init megashop
cd megashop
# 2. Install core dependencies
npm install @pinia/nuxt @nuxtjs/tailwindcss
# 3. Create directory structure
mkdir -p pages/products pages/categories
mkdir -p components/product
mkdir -p composables
mkdir -p server/api/products server/api/cart
mkdir -p layouts
mkdir -p middleware
mkdir -p plugins
mkdir -p assets/css
mkdir -p public
# 4. Initialize Git repository
git init
git add .
git commit -m "feat: initialize MegaShop with Nuxt 3"
# 5. Start development server
npm run dev
❓ FAQ
components subdirectory have a prefix?components/product/Card.vue becomes <ProductCard />. You can disable this by setting components: [{ path: '~/components', pathPrefix: false }] in nuxt.config.ts.runtimeConfig?public section.app.vue and pages/ coexist?app.vue must include <NuxtPage /> to render the page. If there is no pages/ directory, app.vue is the only page.assets and public?assets/ are built by Vite (they can be referenced, optimized, and hashed), while files in public/ are copied as-is to the output directory and can be accessed directly via URL.nuxi prepare or npm run dev will automatically regenerate it.📖 Summary
- Use
npx nuxi@latest initto create a project; pnpm is recommended as the package manager - Nuxt 3 core directories: pages (routes), components (components), composables (functions), server (API), layouts (layouts)
nuxt.config.tsis the project's core configuration:runtimeConfigmanages secrets, androuteRulesmanages rendering strategies- auto-imports eliminates the need to manually import components, Composables, and utility functions
- The MegaShop directory structure must follow the conventions to ensure that all files are placed in the correct locations.
📝 Exercises
- Basic Problem (Difficulty ⭐): Create a project using
nuxi init, and draw the directory tree for your project. - Advanced Exercise (Difficulty: ⭐⭐): Create a component with two levels of subdirectories under
components/to verify the naming conventions used during automatic import (e.g., what is the tag name forcomponents/shop/product/Card.vue?). - Challenge (Difficulty: ⭐⭐⭐): Configure the
routeRulesinnuxt.config.tsso that the home page is pre-rendered, the product page uses ISR for 60 seconds, and the admin page uses CSR, then verify that it works as expected.
---|



