Nuxt.js is a powerful Vue.js framework that simplifies the development of universal Vue applications. It provides automatic code splitting, server-side rendering, static site generation, and a modular architecture for building modern web applications.
What is Nuxt.js?
Nuxt.js is a powerful Vue.js framework that simplifies the development of universal Vue applications. Created by Sébastien Chopin and Alexandre Chopin, Nuxt.js provides a robust foundation for building modern web applications with features like server-side rendering (SSR), static site generation (SSG), automatic code splitting, and a modular architecture.
Key Features
Universal Applications
Nuxt.js enables you to build universal applications that work on both client and server sides.
// pages/index.vue
<template>
<div>
<h1>{{ title }}</h1>
<p>{{ description }}</p>
</div>
</template>
<script>
export default {
data() {
return {
title: 'Welcome to Nuxt.js',
description: 'A powerful Vue.js framework'
}
}
}
</script>
Automatic Routing
Nuxt.js automatically creates routes based on your file structure in the pages directory.
pages/
├── index.vue # / (home page)
├── about.vue # /about
├── users/
│ ├── index.vue # /users
│ └── _id.vue # /users/:id
└── blog/
├── index.vue # /blog
└── _slug.vue # /blog/:slug
Server-Side Rendering (SSR)
Nuxt.js provides built-in SSR capabilities for better SEO and performance.
// pages/users/_id.vue
<template>
<div>
<h1>User: {{ user.name }}</h1>
<p>Email: {{ user.email }}</p>
</div>
</template>
<script>
export default {
async asyncData({ params, $axios }) {
const user = await $axios.$get(`/api/users/${params.id}`)
return { user }
}
}
</script>
Rendering Modes
Universal Mode (SSR)
The default mode that renders pages on both server and client.
// nuxt.config.js
export default {
ssr: true, // Default - renders on server and client
target: 'server'
}
Static Site Generation (SSG)
Generate static HTML files for deployment to CDNs.
// nuxt.config.js
export default {
target: 'static',
generate: {
fallback: true // Generate 404.html for SPA fallback
}
}
// Generate static pages
// nuxt generate
Single Page Application (SPA)
Client-side only rendering for dynamic applications.
// nuxt.config.js
export default {
ssr: false,
target: 'static'
}
Core Concepts
Pages
Pages are Vue components that automatically become routes.
// pages/blog/_slug.vue
<template>
<article>
<h1>{{ post.title }}</h1>
<div v-html="post.content"></div>
</article>
</template>
<script>
export default {
async asyncData({ params, $axios }) {
const post = await $axios.$get(`/api/posts/${params.slug}`)
return { post }
},
head() {
return {
title: this.post.title,
meta: [
{ hid: 'description', name: 'description', content: this.post.excerpt }
]
}
}
}
</script>
Layouts
Layouts provide consistent page structure across your application.
// layouts/default.vue
<template>
<div>
<nav>
<NuxtLink to="/">Home</NuxtLink>
<NuxtLink to="/about">About</NuxtLink>
</nav>
<main>
<Nuxt /> <!-- Page content goes here -->
</main>
<footer>
<p>© 2024 My App</p>
</footer>
</div>
</template>
Components
Auto-imported components for better development experience.
// components/UserCard.vue
<template>
<div class="user-card">
<img :src="user.avatar" :alt="user.name">
<h3>{{ user.name }}</h3>
<p>{{ user.email }}</p>
</div>
</template>
<script>
export default {
props: {
user: {
type: Object,
required: true
}
}
}
</script>
// Use anywhere without importing
<template>
<div>
<UserCard :user="currentUser" />
</div>
</template>
Data Fetching
asyncData
Fetch data on the server side before rendering.
export default {
async asyncData({ $axios, params }) {
const [user, posts] = await Promise.all([
$axios.$get(`/api/users/${params.id}`),
$axios.$get(`/api/users/${params.id}/posts`)
])
return { user, posts }
}
}
fetch
Fetch data on both server and client sides.
export default {
data() {
return {
posts: []
}
},
async fetch() {
this.posts = await this.$axios.$get('/api/posts')
}
}
Composition API (Nuxt 3)
Modern Vue 3 Composition API for data fetching.
// Nuxt 3 with Composition API
<script setup>
const { data: posts } = await useFetch('/api/posts')
const { data: user } = await useLazyFetch('/api/user')
</script>
Modules System
Built-in Modules
Nuxt.js comes with essential modules pre-configured.
// nuxt.config.js
export default {
modules: [
'@nuxtjs/axios', // HTTP client
'@nuxtjs/pwa', // Progressive Web App
'@nuxtjs/auth', // Authentication
'@nuxtjs/i18n' // Internationalization
],
axios: {
baseURL: 'https://api.example.com'
},
pwa: {
manifest: {
name: 'My Nuxt App',
short_name: 'NuxtApp'
}
}
}
Custom Modules
Create reusable modules for your application.
// modules/my-module.js
export default function (moduleOptions) {
// Add plugin
this.addPlugin({
src: require.resolve('./plugin.js'),
options: moduleOptions
})
// Add server middleware
this.addServerMiddleware({
path: '/api',
handler: '~/server-middleware/api.js'
})
}
// nuxt.config.js
export default {
modules: [
'~/modules/my-module'
],
myModule: {
// module options
}
}
SEO and Meta Tags
Dynamic Meta Tags
Set meta tags dynamically for better SEO.
export default {
head() {
return {
title: this.post.title,
meta: [
{ hid: 'description', name: 'description', content: this.post.excerpt },
{ hid: 'og:title', property: 'og:title', content: this.post.title },
{ hid: 'og:description', property: 'og:description', content: this.post.excerpt },
{ hid: 'og:image', property: 'og:image', content: this.post.image }
]
}
}
}
Structured Data
Add JSON-LD structured data for search engines.
export default {
head() {
return {
script: [
{
type: 'application/ld+json',
json: {
'@context': 'https://schema.org',
'@type': 'Article',
headline: this.post.title,
author: {
'@type': 'Person',
name: this.post.author
}
}
}
]
}
}
}
Performance Optimization
Automatic Code Splitting
Nuxt.js automatically splits your code for optimal loading.
// Automatic route-based code splitting
// Each page is loaded only when needed
// Manual code splitting
const MyComponent = () => import('~/components/MyComponent.vue')
Image Optimization
Optimize images with the @nuxt/image module.
// nuxt.config.js
export default {
modules: ['@nuxt/image'],
image: {
provider: 'ipx',
quality: 80
}
}
// Usage
<template>
<nuxt-img src="/image.jpg" width="300" height="200" />
</template>
Getting Started
Installation
# Create new Nuxt.js project
npx create-nuxt-app my-nuxt-app
# Or with yarn
yarn create nuxt-app my-nuxt-app
# Manual installation
npm install nuxt
Basic Setup
// nuxt.config.js
export default {
// Global page headers
head: {
title: 'My Nuxt App',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
]
},
// Global CSS
css: [
'~/assets/css/main.css'
],
// Plugins
plugins: [
'~/plugins/axios.js'
],
// Auto import components
components: true,
// Build Configuration
build: {
// You can extend webpack config here
}
}
Development Commands
# Development server
npm run dev
# Build for production
npm run build
# Start production server
npm run start
# Generate static site
npm run generate
Best Practices
Project Structure
Performance
SEO
Nuxt.js has become a popular choice for Vue.js developers, offering a comprehensive framework that simplifies the development of modern web applications while providing excellent performance and SEO capabilities.