Guide·

Getting Started with Nuxt

Learn how to build modern web applications with Nuxt, the intuitive Vue framework.
Getting Started with Nuxt
Nuxt is a free and open-source framework that makes web development intuitive and powerful. It's built on top of Vue.js and provides everything you need to create production-ready applications.

Why Nuxt?

File-Based Routing

Automatic routes based on your file structure

Server-Side Rendering

Built-in SSR for better SEO and performance

Auto Imports

Components and composables are auto-imported

Quick Start

Create a new Nuxt project with a single command:

npx nuxi@latest init my-app
cd my-app
npm install
npm run dev

Your app will be running at http://localhost:3000.

Directory Structure

Nuxt uses a convention-based directory structure:

my-app/
├── app/
│   ├── components/    # Auto-imported Vue components
│   ├── composables/   # Auto-imported composable functions
│   ├── layouts/       # Layout templates
│   ├── pages/         # File-based routing
│   └── app.vue        # Main app component
├── public/            # Static assets
├── server/            # Server routes and middleware
└── nuxt.config.ts     # Nuxt configuration

Pages and Routing

Create files in the pages/ directory and they automatically become routes:

<!-- pages/index.vue → / -->
<template>
  <div>
    <h1>Home Page</h1>
  </div>
</template>
<!-- pages/about.vue → /about -->
<template>
  <div>
    <h1>About Page</h1>
  </div>
</template>

Dynamic Routes

Use square brackets for dynamic parameters:

<!-- pages/posts/[id].vue → /posts/1, /posts/2, etc. -->
<script setup>
  const route = useRoute()
  const postId = route.params.id
</script>

<template>
  <div>
    <h1>Post {{ postId }}</h1>
  </div>
</template>

Layouts

Create reusable page layouts in the layouts/ directory:

<!-- layouts/default.vue -->
<template>
  <div>
    <header>
      <nav>My App</nav>
    </header>
    <main>
      <slot />
    </main>
    <footer>© 2025</footer>
  </div>
</template>

Use a specific layout in a page:

<!-- pages/dashboard.vue -->
<script setup>
  definePageMeta({
    layout: "admin",
  })
</script>

<template>
  <div>Dashboard content</div>
</template>

Data Fetching

Nuxt provides powerful composables for fetching data:

useFetch

The simplest way to fetch data:

<script setup>
  const { data: posts, status } = await useFetch("/api/posts")
</script>

<template>
  <div v-if="status === 'pending'">Loading...</div>
  <div v-else>
    <article v-for="post in posts" :key="post.id">
      <h2>{{ post.title }}</h2>
    </article>
  </div>
</template>

useAsyncData

For more control over data fetching:

<script setup>
  const { data: user } = await useAsyncData("user", () => {
    return $fetch(`/api/users/${userId}`)
  })
</script>

Composables

Create reusable logic in the composables/ directory:

// composables/useCounter.ts
export function useCounter(initial = 0) {
  const count = ref(initial)

  function increment() {
    count.value++
  }

  function decrement() {
    count.value--
  }

  return { count, increment, decrement }
}

Use it in any component (auto-imported):

<script setup>
  const { count, increment, decrement } = useCounter(10)
</script>

<template>
  <button @click="decrement">-</button>
  <span>{{ count }}</span>
  <button @click="increment">+</button>
</template>

SEO and Meta Tags

Nuxt makes SEO easy with the useSeoMeta composable:

<script setup>
  useSeoMeta({
    title: "My Amazing Page",
    description: "This is a description of my page",
    ogTitle: "My Amazing Page",
    ogDescription: "This is a description for social sharing",
    ogImage: "/og-image.png",
    twitterCard: "summary_large_image",
  })
</script>

Or use the useHead composable for full control:

<script setup>
  useHead({
    title: "My Page",
    meta: [{ name: "description", content: "Page description" }],
    link: [{ rel: "canonical", href: "https://example.com/page" }],
  })
</script>

Middleware

Add route middleware for authentication, redirects, and more:

// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
  const isAuthenticated = false // Your auth logic

  if (!isAuthenticated && to.path !== "/login") {
    return navigateTo("/login")
  }
})

Apply middleware to a page:

<script setup>
  definePageMeta({
    middleware: "auth",
  })
</script>

Server Routes

Create API endpoints in the server/ directory:

// server/api/hello.ts
export default defineEventHandler((event) => {
  return {
    message: "Hello from the server!",
  }
})

Access it at /api/hello.

Deployment

Nuxt supports multiple deployment targets:

Vercel

Zero-config deployment with edge functions

Netlify

Automatic builds and serverless functions

Cloudflare

Global edge network with Workers

Build your app for production:

npm run build

Or generate a static site:

npm run generate
Explore the Nuxt documentation for more features like modules, plugins, and advanced configuration.
Enjoyed this post?
Subscribe to get notified when I publish new articles.

Need a Full Stack Engineer?

10+ years building performant web applications. Let's talk about your next project.