Introduction
Nuxt.js is a framework based on Vue.js that supports Server-Side Rendering (SSR) and Static Site Generation (SSG). It provides a straightforward way to build high-performance Vue.js applications. Nuxt.js automates many best practices, such as routing, state management, and optimization, allowing developers to focus on business logic rather than framework details.
Installation
To start using Nuxt.js, ensure you have Node.js and npm installed. Once your environment is set up, create a new Nuxt.js project with the following command:
npx create-nuxt-app my-nuxt-projectThis will guide you through the project initialization process, where you can customize options such as using TypeScript, selecting a CSS preprocessor, and more.
Basic Configuration
After creating the project, you can customize its configuration by editing the nuxt.config.js file located in the project’s root directory. This file is used to override Nuxt.js’s default behavior.
Configuration Example
Here’s a simple nuxt.config.js example:
// nuxt.config.js
export default {
// Target (https://go.nuxtjs.dev/config-target)
target: 'static',
// Global page headers (https://go.nuxtjs.dev/config-head)
head: {
title: 'my-nuxt-project',
htmlAttrs: {
lang: 'en',
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' },
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
],
},
// Global CSS (https://go.nuxtjs.dev/config-css)
css: [
'~assets/scss/main.scss',
],
// Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)
plugins: [
'~/plugins/my-plugin.js',
],
// Auto import components (https://go.nuxtjs.dev/config-components)
components: true,
// Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules)
buildModules: [
// https://go.nuxtjs.dev/eslint
'@nuxtjs/eslint-module',
// https://go.nuxtjs.dev/tailwindcss
'@nuxtjs/tailwindcss',
],
// Modules (https://go.nuxtjs.dev/config-modules)
modules: [
// https://go.nuxtjs.dev/axios
'@nuxtjs/axios',
// https://go.nuxtjs.dev/pwa
'@nuxtjs/pwa',
],
// Axios module configuration (https://go.nuxtjs.dev/config-axios)
axios: {},
// Build Configuration (https://go.nuxtjs.dev/config-build)
build: {},
};Directory Structure
The typical directory structure of a Nuxt.js project is as follows:
my-nuxt-project/
├── .nuxt/ # Nuxt-generated folder containing compiled files
├── assets/ # Static assets like CSS, JavaScript, images, etc.
├── components/ # Vue components
├── layouts/ # Page layouts
├── middleware/ # Middleware
├── pages/ # Vue pages
├── plugins/ # Plugins
├── static/ # Static files, copied to the output directory
├── store/ # Vuex store
├── nuxt.config.js # Nuxt.js configuration file
├── package.json # Project dependencies
└── ....nuxt/: Auto-generated by Nuxt, contains compiled files.assets/: Stores static assets like CSS, JavaScript, and images.components/: Vue components.layouts/: Page layouts.middleware/: Middleware for operations before or after page loading.pages/: Vue pages, each file corresponding to a URL.plugins/: Plugins to extend Vue instance functionality.static/: Static files, copied directly to the output directory.store/: Vuex store for managing application state.
Running the Project
After installing dependencies and configuring the project, start the development server with:
npm run devOr, if using Yarn:
yarn devThis launches a development server that watches for file changes, automatically recompiling and refreshing the browser.
Views
Views are a core part of Nuxt.js applications, responsible for displaying data to users. Nuxt.js uses Vue.js Single File Components (SFCs) as the building blocks for views.
Creating Views
View files are typically placed in the pages/ directory, with each file representing a view and its filename determining the corresponding URL.
// pages/index.vue
<template>
<div>
<h1>Welcome to Nuxt.js!</h1>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello from Nuxt.js!',
};
},
};
</script>Styles
Nuxt.js supports multiple CSS preprocessors, including SCSS, SASS, LESS, and Stylus. Style files can be placed in the assets/ directory and specified in nuxt.config.js.
Using Global Styles
Create a style file in the assets/ directory and declare it in nuxt.config.js.
Example:
// nuxt.config.js
export default {
css: ['~/assets/scss/main.scss'],
};main.scss file content:
// assets/scss/main.scss
body {
font-family: 'Arial', sans-serif;
background-color: #f4f4f4;
}Using Local Styles
Use scoped styles within individual components or pages.
// pages/index.vue
<template>
<div class="welcome">
<h1>Welcome to Nuxt.js!</h1>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello from Nuxt.js!',
};
},
};
</script>
<style scoped>
.welcome {
background-color: #fff;
padding: 20px;
border: 1px solid #ccc;
}
</style>Assets
Asset files (e.g., images, fonts) are typically placed in the static/ directory. These files are copied directly to the output directory.
<!-- pages/index.vue -->
<img src="~/static/images/logo.png" alt="Logo" />Basic Application
Layouts
Layouts define the common structure of pages, such as headers and footers, reducing repetitive code.
Creating a Layout
Layout files are typically placed in the layouts/ directory.
// layouts/default.vue
<template>
<div>
<header>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<main>
<nuxt />
</main>
<footer>
<p>© {{ new Date().getFullYear() }} My App</p>
</footer>
</div>
</template>Using the Default Layout:
// pages/index.vue
<template>
<div>
<h1>Welcome to Nuxt.js!</h1>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello from Nuxt.js!',
};
},
};
</script>Using Multiple Layouts
Create multiple layout files in the layouts/ directory and selectively use them in pages.
// layouts/admin.vue
<template>
<div>
<header>
<nav>
<ul>
<li><a href="/admin">Admin Dashboard</a></li>
<li><a href="/admin/settings">Settings</a></li>
</ul>
</nav>
</header>
<main>
<nuxt />
</main>
<footer>
<p>© {{ new Date().getFullYear() }} Admin Panel</p>
</footer>
</div>
</template>Using a Specific Layout in a Page:
// pages/admin/index.vue
<template>
<div>
<h1>Welcome to the Admin Panel!</h1>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
layout: 'admin',
data() {
return {
message: 'Hello from Admin Panel!',
};
},
};
</script>Components
Components are the fundamental building blocks in Vue.js and a key part of Nuxt.js applications.
Creating Components
Component files are typically placed in the components/ directory.
// components/HelloWorld.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
props: {
msg: String,
},
};
</script>
<style scoped>
.hello {
color: #42b983;
}
</style>Using Components in Pages:
// pages/index.vue
<template>
<div>
<h1>Welcome to Nuxt.js!</h1>
<HelloWorld msg="Hello from Nuxt.js!" />
</div>
</template>
<script>
import HelloWorld from '~/components/HelloWorld.vue';
export default {
components: {
HelloWorld,
},
};
</script>Dynamic Routing
Dynamic routing allows you to create different pages based on parameters.
Creating Dynamic Pages
Create folders starting with square brackets in the pages/ directory.
// pages/posts/_id.vue
<template>
<div>
<h1>Post ID: {{ id }}</h1>
<p>{{ post.title }}</p>
</div>
</template>
<script>
export default {
asyncData({ params, $axios }) {
return $axios.$get(`/api/posts/${params.id}`).then(res => {
return { post: res };
});
},
};
</script>URL Examples:
/posts/1
/posts/2Asynchronous Data
Asynchronous data fetching allows you to retrieve data from the server when a page loads.
Using the asyncData Function
Use the asyncData function in components or pages to fetch asynchronous data.
// pages/index.vue
<template>
<div>
<h1>Welcome to Nuxt.js!</h1>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
async asyncData({ $axios }) {
const response = await $axios.$get('/api/data');
return { message: response.message };
},
};
</script>Vuex Store
Vuex is the official state management library for Vue.js, and Nuxt.js provides built-in support.
Creating a Vuex Store
Create a Vuex store in the store/ directory.
// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
count: 0,
},
mutations: {
increment(state) {
state.count++;
},
},
actions: {
increment({ commit }) {
commit('increment');
},
},
getters: {
count: state => state.count,
},
});Using Vuex in Pages:
// pages/index.vue
<template>
<div>
<h1>Welcome to Nuxt.js!</h1>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script>
export default {
computed: {
count() {
return this.$store.getters.count;
},
},
methods: {
increment() {
this.$store.dispatch('increment');
},
},
};
</script>Middleware
Middleware allows you to execute logic before or after page loading.
Creating Middleware
Create middleware in the middleware/ directory.
// middleware/authenticated.js
export default function ({ store, redirect }) {
if (!store.getters['auth/isAuthenticated']) {
return redirect('/login');
}
}Using Middleware in Pages:
// pages/admin/index.vue
export default {
middleware: 'authenticated',
};Plugins
Plugins extend the functionality of Vue instances, such as adding global methods, mixins, or event listeners.
Creating Plugins
Create plugin files in the plugins/ directory.
// plugins/vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify';
import 'vuetify/dist/vuetify.min.css';
Vue.use(Vuetify);
export default new Vuetify({
theme: {
themes: {
light: {
primary: '#3f51b5',
secondary: '#b0bec5',
accent: '#8c9eff',
error: '#b71c1c',
},
},
},
});Register the plugin in nuxt.config.js:
// nuxt.config.js
export default {
plugins: ['~/plugins/vuetify.js'],
};Internationalization
Nuxt.js supports various internationalization solutions, such as nuxt-i18n.
Install nuxt-i18n
npm install --save nuxt-i18nConfigure nuxt-i18n in nuxt.config.js:
// nuxt.config.js
export default {
i18n: {
locales: [
{ code: 'en', iso: 'en-US', file: 'en-US.js' },
{ code: 'zh', iso: 'zh-CN', file: 'zh-CN.js' },
],
defaultLocale: 'en',
vueI18n: {
fallbackLocale: 'en',
messages: {},
},
},
};Create Language Files:
// locales/en-US.js
export default {
message: 'Hello from Nuxt.js!',
};
// locales/zh-CN.js
export default {
message: '你好,来自 Nuxt.js!',
};Using Internationalization in Pages:
// pages/index.vue
<template>
<div>
<h1>Welcome to Nuxt.js!</h1>
<p>{{ $t('message') }}</p>
</div>
</template>SEO and Meta Tags
Nuxt.js provides strong support for SEO, allowing customization of meta tags via the head property.
Customizing Meta Tags
Use the head property in pages to customize meta tags.
// pages/index.vue
export default {
head() {
return {
title: 'Welcome to Nuxt.js!',
meta: [
{ hid: 'description', name: 'description', content: 'My amazing Nuxt.js application' },
],
};
},
};Code Splitting
Nuxt.js supports dynamic imports for on-demand loading and code splitting.
Using Dynamic Imports
Use import() in asyncData or fetch methods for code splitting.
// pages/posts/_id.vue
export default {
async asyncData({ params, $axios }) {
const Post = await import('~/models/Post');
const post = await $axios.$get(`/api/posts/${params.id}`);
return { post: new Post(post) };
},
};Error Handling
Nuxt.js provides mechanisms for handling errors at a global level.
Global Error Handling
Handle errors in the pages/_error.vue file.
// pages/_error.vue
<template>
<div>
<h1>Error {{ statusCode }}</h1>
<p>{{ errorMessage }}</p>
</div>
</template>
<script>
export default {
props: {
statusCode: Number,
errorMessage: String,
},
};
</script>Configure error handling in nuxt.config.js:
// nuxt.config.js
export default {
error: {
statusCode: 500,
message: 'Internal Server Error',
},
};Server-Side Rendering (SSR)
Nuxt.js supports server-side rendering by default, significantly improving first-page load speed and SEO.
Configuring SSR
Control the rendering mode via the target configuration option.
// nuxt.config.js
export default {
target: 'server',
};Static Site Generation (SSG)
Nuxt.js supports static site generation, creating pre-rendered HTML files.
Configuring SSG
Enable SSG by setting the target configuration option to static.
// nuxt.config.js
export default {
target: 'static',
};Production Deployment
Nuxt.js supports various deployment methods, including traditional server deployment and modern serverless deployment.
Traditional Server Deployment
Use nuxt build and nuxt start commands to build and start the production application.
npm run build
npm run startServerless Deployment
Deploy to platforms like Netlify or Vercel for serverless deployment.
# Deploy with Vercel
vercelPerformance Optimization
Nuxt.js offers various performance optimization techniques, including lazy loading and caching strategies.
Lazy Loading
Use import() in asyncData or fetch methods for code splitting.
// pages/posts/_id.vue
export default {
async asyncData({ params, $axios }) {
const Post = await import('~/models/Post');
const post = await $axios.$get(`/api/posts/${params.id}`);
return { post: new Post(post) };
},
};Caching Strategies
Leverage browser caching, CDN caching, and other strategies to reduce network requests.
// nuxt.config.js
export default {
router: {
base: process.env.BASE_URL,
},
};Appendix: Frequently Asked Questions
Q: How do I use Vuex in Nuxt.js?
A: Create Vuex store files in the store/ directory, then access them in pages or components using $store.
Q: How do I use Vue Router in Nuxt.js?
A: Nuxt.js has built-in routing, so Vue Router is not required. Page file names determine route paths.
Q: How do I handle API requests in Nuxt.js?
A: Use $axios in asyncData or fetch methods to handle API requests.
Q: How do I use third-party libraries in Nuxt.js?
A: Install libraries via npm or Yarn, then create plugin files in the plugins/ directory to register and configure them.
Q: How do I implement multi-language support in Nuxt.js?
A: Use the nuxt-i18n plugin for multi-language support, configuring it in nuxt.config.js and using the $t function in pages to switch languages.



