Skip to content
ExponaBLOG
VUE.JS & NUXT · DAY 032 / 100

Nuxt tutorial: getting started for Vue & Nuxt developers

The full-stack Vue framework.

Expona Admin5 min read

If you've built with Vue, you're already halfway there—Nuxt amplifies what you know by layering on file-based routing, server-side rendering, and zero-config auto imports. We'll walk you through the essentials so you can ship full-stack applications faster, with less boilerplate and more predictable architecture.

Why Nuxt matters for Vue developers

Vue gives you a component framework; Nuxt gives you a full-stack framework. The distinction is real. When you step into production, you need routing, data fetching on the server, static site generation, and deployment strategies—things Vue alone doesn't prescribe. Nuxt bundles these concerns into a cohesive workflow that feels natural if you're already fluent in Vue's component model.

Over the past decade, we've seen teams spend weeks wiring up Next.js or custom server logic for features Nuxt handles out of the box. A Nuxt tutorial designed for Vue developers isn't about learning a new language—it's about learning where to put your code so the framework handles the plumbing.

Create a project — npx nuxi@latest init my-app

Getting a Nuxt app running takes one command and roughly two minutes.

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

Open http://localhost:3000 and you'll see the default welcome page. Under the hood, Nuxt has scaffolded a nuxt.config.ts, a package.json with all the build tooling configured, and a minimal folder structure ready for your app.

Let's say you're building an internal dashboard for a ride-hailing team. You need authentication, real-time data, and a fast dev loop. The scaffolder creates:

  • app.vue – your root component
  • pages/ – where routes live
  • components/ – reusable UI
  • server/ – optional backend API routes
  • composables/ – shared Vue composition functions

This structure isn't enforced by Nuxt's code—it's the mental model. You organize by concern, and the framework auto-detects and wires everything together. No webpack config, no route definitions in JavaScript: the file system is your source of truth.

For teams migrating from a sprawling SPA, this is revelatory. You delete routing logic, lose the need for a separate Next.js or Express layer for basic server-side rendering, and your developers spend time on features, not plumbing.

File-based routing — pages/ folder creates routes automatically

Nuxt's routing engine watches the pages/ directory. Create a file, get a route—no configuration required.

If you create pages/dashboard.vue, Nuxt automatically serves it at /dashboard. Create pages/drivers/[id].vue, and you get dynamic segments: /drivers/123 binds 123 to a route param called id. Create pages/admin/users/index.vue, and it maps to /admin/users. The pattern mirrors your file tree.

Let's build a simplified driver detail page for that ride-hailing dashboard:

typescript


  <div>
    <h1>Driver {{ route.params.id }}</h1>
    <p>Loading...</p>
    <div>
      <p>Name: {{ driver.name }}</p>
      <p>Rating: {{ driver.rating }}/5</p>
    </div>
  </div>


The [id] becomes a dynamic parameter, accessed via useRoute().params.id. No router configuration file. No manual route registration. This convention-over-configuration approach is what makes Nuxt appealing for teams shipping iteratively.

Nested routes work the same way. A file at pages/admin/drivers/index.vue renders at /admin/drivers. Nuxt also supports layout routes, catch-all routes with [...slug].vue, and middleware-per-route. For a CRM or internal tool, this simplicity is transformative.

Auto imports — Components and composables without import statements

One of Nuxt's most time-saving features: auto imports. Place a component in components/, and it's available in your templates without an import statement. Same for functions in composables/.

Imagine you're building a reusable form for driver onboarding. Create components/DriverForm.vue:

typescript


  
    
    
    Register
  


Now use it anywhere without importing:

typescript


  <div>
    <h1>Driver Onboarding</h1>
     
  </div>


This is massive in practice. Over hundreds of components, you avoid repetitive import boilerplate and reduce cognitive load. Nuxt's auto-import is opinionated—it assumes you want this behavior—and it's opt-out if you need granular control.

The same applies to composables. Create composables/useDrivers.ts:

typescript
// composables/useDrivers.ts
export const useDrivers = () => {
  const drivers = ref([])
  
  const fetchDrivers = async () => {
    drivers.value = await $fetch('/api/drivers')
  }
  
  return { drivers, fetchDrivers }
}

Use it in any component:

typescript

This pattern scales beautifully across teams. New developers onboarded to the project quickly understand the structure without memorizing import paths.

Rendering modes — SSR by default, with SSG and hybrid options

Nuxt defaults to SSR (server-side rendering), which means your pages render on the server before reaching the browser. This is powerful for SEO, initial load performance, and data-driven pages.

In your nuxt.config.ts, you control the rendering mode:

typescript
// nuxt.config.ts
export default defineNuxtConfig({
  ssr: true, // SSR enabled (default)
})

When a user visits your site, the server executes your Vue components, fetches data, and sends HTML. The browser receives a fully-rendered page, then hydrates it with interactivity. For a travel booking platform or e-commerce site, this is critical: Google sees your content immediately, and users see something faster.

For static sites—blogs, documentation, landing pages—use SSG (static site generation):

typescript
// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    prerender: {
      crawlLinks: true,
      routes: ['/sitemap.xml'],
      ignore: ['/admin']
    }
  }
})

Running npm run build pre-renders routes to static HTML files. Deploy to a CDN. Zero server compute required.

For hybrid rendering, use Nuxt's route rules to cache certain pages and serve others dynamically:

typescript
// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },           // static at build time
    '/blog/**': { cache: { maxAge: 60 * 10 } }, // cache 10 mins
    '/api/**': { noCache: true },       // always dynamic
  }
})

This flexibility is why Nuxt works across SPA, SSR, SSG, and hybrid architectures without context-switching. One framework, multiple deployment strategies.

Common mistakes

Over-fetching in components. Developers new to Nuxt often fetch data in onMounted hooks, losing the SSR advantage. Instead, use useFetch or useAsyncData at the top level of a page—Nuxt handles server execution and dehydration automatically.

typescript




Forgetting middleware ordering. If you apply middleware globally in nuxt.config.ts, remember that order matters. Authentication middleware should run before route protection.

Mixing file-based and programmatic routing. Nuxt prefers file-based routing. If you define routes in code, you lose the auto-detection benefit. Stick to the pages/ folder convention.

Ignoring layout scope. Layouts wrap pages but don't share scope. State in a layout isn't automatically available in pages. Use Pinia or context composables instead.

Key takeaways

  • Nuxt is a production-ready framework that extends Vue with routing, SSR, and zero-config auto imports—essential for full-stack apps.
  • File-based routing eliminates route configuration; the pages/ folder is your router.
  • Auto imports for components and composables reduce boilerplate and improve developer velocity across teams.
  • SSR, SSG, and hybrid rendering modes let you optimize for SEO, performance, and deployment strategy without code rewrites.
  • Start with the default SSR setup, then shift rendering modes as your app evolves.
  • Fetch data at the page level using useFetch or useAsyncData to leverage server-side rendering, not in mounted hooks.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles