Nuxt 3 Knowledge Base
Setup
npx nuxi@latest init my-app
cd my-app
npm install
Project Structure
├── app.vue
├── nuxt.config.ts
├── pages/
│ ├── index.vue
│ ├── [locale]/
│ │ └── index.vue
│ └── about.vue
├── components/
│ ├── Header.vue
│ └── Footer.vue
├── composables/
│ └── useAuth.ts
├── server/
│ ├── api/
│ │ └── contact.post.ts
│ └── middleware/
├── layouts/
│ └── default.vue
└── i18n/
└── locales/
Pages
<!-- pages/[locale]/index.vue -->
<script setup lang="ts">
const { locale } = useRoute().params;
const { t } = useI18n();
// Fetch data
const { data: posts } = await useFetch('/api/posts');
</script>
<template>
<div>
<h1>{{ t('home.title') }}</h1>
<div v-for="post in posts" :key="post.id">
{{ post.title }}
</div>
</div>
</template>
Data Fetching
<script setup lang="ts">
// useFetch - SSR friendly
const { data, pending, error, refresh } = await useFetch('/api/posts');
// useAsyncData - More control
const { data } = await useAsyncData('posts', () => {
return $fetch('/api/posts');
});
// Lazy loading
const { data } = useLazyFetch('/api/posts');
</script>
Server API
// server/api/contact.post.ts
import { z } from 'zod';
const schema = z.object({
name: z.string().min(2),
email: z.string().email(),
message: z.string().min(10),
});
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const data = schema.parse(body);
// Process...
return { success: true };
});
Composables
// composables/useAuth.ts
export function useAuth() {
const user = useState<User | null>('user', () => null);
async function login(email: string, password: string) {
const data = await $fetch('/api/auth/login', {
method: 'POST',
body: { email, password },
});
user.value = data.user;
}
function logout() {
user.value = null;
}
return { user, login, logout };
}
Layouts
<!-- layouts/default.vue -->
<template>
<div>
<Header />
<main>
<slot />
</main>
<Footer />
</div>
</template>
<!-- pages/about.vue -->
<script setup>
definePageMeta({
layout: 'default',
});
</script>
Middleware
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
const { user } = useAuth();
if (!user.value && to.path !== '/login') {
return navigateTo('/login');
}
});
Config
// nuxt.config.ts
export default defineNuxtConfig({
devtools: { enabled: true },
modules: [
'@nuxtjs/tailwindcss',
'@nuxtjs/i18n',
],
i18n: {
locales: ['it', 'en', 'cs'],
defaultLocale: 'it',
},
app: {
head: {
title: 'My App',
},
},
});
Best Practices
- Auto-imports - Components, composables auto-imported
- useFetch - For SSR data fetching
- Server routes - /server/api for backend
- Composables - Reusable logic
- Nitro - Universal deployment