Nuxt.js is the most intuitive Vue framework available today. It combines the power of Vue.js with server-side rendering features to make it more powerful. You can build a complete Vue.js client-side rendering application, a comprehensive static generated application, and a monolith application.

Nuxt.js solves the problem of structuring your Vue.js project as it comes with enterprise-ready frontend development architecture. The features of Nuxt.js are already structured using industry standards to create enterprise applications.

This guide will explore Nuxt.js, what you can build with it, and how it works from the inside out.


What Is Nuxt.js?

Nuxt.js is a server-side rendering framework built on Vue.js. It abstracts away most of the complex configuration involved in managing asynchronous data, middleware, and routing. It also helps structure Vue.js applications using industry-standard architecture for building simple or enterprise Vue.js applications.

A screenshot showing Nuxt.js official logo.
Nuxt.js official logo. (Image source: Medium)

What Is Nuxt.js Used For?

Nuxt.js allows you to create many different kinds of applications. Below are the three most popular applications made with Nuxt.js.

Static Generated Pages

This type of website does not require any external content source — the content is already embedded in the HTML. Examples of such websites include portfolio, demo, and tutorial websites.

Single-Page Applications (SPA)

This frontend development approach fetches dynamic content from an external API and displays it on the client-side. Most JavaScript frameworks such as React.js, Vue.js, Angular, and Ember.js are all single-page application frameworks.

What’s more, a SPA’s routing system is achieved with HTML 5 History API or the location hash for routing, which gives developers the ability to modify a website’s URL without a full page refresh.

Universal Applications

“Universal application” is a term that describes the use of a server-side rendering approach to fetch client-side data on the server before fully rendering the page on the client browser.

Server-side rendering (SSR) is a known issue in Vue.js because it involves tedious configurations to get it right.

Nuxt.js solves the SSR problem in Vue.js, which is helpful for search engine optimization (SEO). Nuxt.js can even extend Universal applications to accommodate a full-fledged monolith application, where the frontend and backend share a single codebase.

How Does Nuxt.js Work?

Nuxt.js works the same way a server-side framework works when a user visits a website. If server-side rendering is enabled, the requests are rendered on the server each time the user requests a page, therefore a server is needed to be able to serve the page on each request. Also, if client-side rendering is enabled, it renders the content of the page in the browser using JavaScript.

These are the main actions and methods used in Nuxt.js:

  • nuxtServerInit (Action): This is the first lifecycle hook that is called on the server-side if Vuex store is enabled. It is a Vuex action that is called only on server-side to pre-populate the store and finally, it can be used to dispatch other actions in the Vuex store.
  • validate() (Function): The validate method is called before rendering page components. It is useful to validate dynamic parameters of a page component.
  • The asyncData() method is used to fetch data and render the data on the server-side, while the fetch() method is used to fill the store before rendering the page.

For instance, when a Nuxt.js site receives an initial page visit, it calls out to the nuxtServerInit action to update the Vuex states (if defined in the Vuex store). Otherwise, if the nuxtServerInit is not defined, it moves on to a different stage.

Next, it looks up for middlewares in this order. First, it checks the nuxt.config.js file for any global middleware. If it’s defined, it will be executed before checking the layout pages for middleware. Lastly, it will execute the individual page middleware, including the page children.

After executing all the middlewares in order, it will check if the route is dynamic and execute the validate() method created and validated.

Next, it calls the page’s asyncData() method to fetch and render data on the server-side before calling the fetch() method to populate the Vuex store on the client-side.

By this point, the page should have all the data and content needed to display a proper web page. Then the page is rendered by the Nuxt.js engine and shown to the visitor, completing the process.

This flowchart illustrates all the steps it takes to render a single page:

A screenshot showing Nuxt.js Lifecycle Hooks and the initialization process.
An overview of Nuxt.js lifecycle hooks. (Source: Nuxt Website)

No matter which tool you use, you will always feel more confident when you understand how the tool works under the hood. With the above explanation of how Nuxt.js works under the hood, it will be easy to understand. Let’s explore the benefits of using Nuxt.js for your next project.

Benefits of Nuxt.js

Next, let’s talk about the benefits of the Nuxt.js framework and why it’s become so popular as of late.

Create Universal Apps Without the Hassle

Nuxt.js makes creating server-side rendering applications very easy. If you have ever tried to develop a server-side-rendered application with Vue.js, you likely jumped difficult hurdles due to the myriad configuration options available for both server-side and client-side.

The SSR feature is already built into Nuxt.js and is easy to use. It gives access to the isServer and isClient properties on your components to decide if you’re rendering something on the client-side or server-side.

It also provides the asyncData method dedicated to fetching and rendering data on the server-side of your page component.

Statically Render Vue Apps With Universal Benefit

Static-generated websites are on the rise in the web industry, and with a single nuxt generate command, you can generate a static version of your website, with all the HTML with corresponding routes.

The nuxt generate command works exactly like the universal application approach with all the SSR features enabled but for a static generated website.

In Nuxt.js, a statically generated website is like building a powerful universal application without a server to power the SSR feature.

Get Automatic Code-splitting

One of the reasons why Nuxt.js is very fast in performance is because of the code splitting feature, where a route is given a single JavaScript file with only the code needed to run that route, therefore, reducing your application size.

This code splitting feature uses Webpack configuration that comes inbuilt when generating a static version of your website.

Hot Reload

Hot reload is a great feature added to resolve the time-consuming change-refresh method of software development.

It is configured to auto-update the development server when you change any file in the root directory.

When developing and working on .vue files, It uses a Webpack configuration to check for changes and compiles everything for you. This approach saves developers time and encourages faster application development.

Get ES6/ES7 Compilation

Nuxt.js comes prebuilt with Webpack and Babel for translating and compiling the latest JavaScript versions like ES6 and ES7 into JavaScript that can run on older browsers.

Babel is configured to compile all .vue files and ES6 code inside the script tags into JavaScript that works on all browsers.

This feature fixes the battle of creating browser-compatible applications manually and setting up the configuration from the ground up.

How To Create a Nuxt.js App

This section will explore how to create a Nuxt.js application. Before we dive in, let’s explore some of the few critical concepts in developing a Nuxt.js application.

Creating Nuxt.js Application

Creating a new project is easy and straight to the point. You can create a project with different approaches as listed in the official documentation, but the most preferred and recommended approach is using the CLI.

To create a new application using the CLI, ensure you have npx installed (npx is shipped by default when you install yarn or npm 5.2.0 above).

Next, type in the following command in the folder you want to place your project:

npx create-nuxt-app 
cd 
npm run dev

Make sure to replace the project-name> with your actual project name.

Understanding Nuxt.js Folder Structure

When you are scaffolding a new application using any of the different installation approaches in the official documentation, you are presented with various files and folders generated by the CLI. These files and folders are vital and require that some of the folders remain unchanged without additional configuration.

We will look at the folder structure, discuss each file and folder, and know their importance.

A screenshot of Nuxt.js folder structure showing different files generated by Nuxt.js CLI.
Newly created Nuxt.js folder structure.

1. .nuxt

The .nuxt directory is hidden and generated when you start your development server, and it’s called the build directory. The directory contains generated files or artifacts when running the npm run build command.

You can modify the files in this directory only for debugging purposes because the files will be auto-generated again once you run the dev or build command.

2. Assets

The assets folder contains all your uncompiled assets such as images, fonts, SASS files, and Stylus. Webpack will compile any file that is included in this directory during the rendering process.

3. Components

The components directory is similar to the components directory in Vue.js, where all your Vue components are stored. Components are the files that make up the different parts of your pages and can be reused and imported into your pages, layouts, and other components too.

4. Layouts

The layouts folder stores the layout of your application and is very useful when separating different structures of your application for either authenticated users or guest users.

You can create many layouts to correspond to the structure of your application. Sometimes, you might want some pages on your website to have different sidebars, headers, footers, etc. These and more are structured using the layout files stored in the layouts folder.

5. Middleware

Middlewares are custom functions that can be executed before rendering either a page or a group of pages (layout) and they can be defined and stored in the middlewares folder in Nuxt.js.

Middlewares are very handy when creating a membership-only website, and if you want to restrict access to certain pages, you can set up middleware to check if a user is logged in or not.

In Nuxt.js, middlewares work similarly to middlewares in any backend programming frameworks such as ExpressJS, Laravel, etc. It has three different types of middleware viz: named, anonymous, and router middleware.

6. Pages

The pages directory is the bedrock of the Nuxt.js routing system as it reads all the .vue files inside this directory and creates the router configuration automatically.

The pages directory contains your application views and routes, and every page component is also a standard Vue component.

Still, Nuxt.js treats it as a route by adding special attributes and functions to make the development of your universal application as easy as possible.

7. Plugins

The plugins directory contains JavaScript codes you want to execute before instantiating the root Vue.js Application. This is the place to add Vue plugins and inject functions or constants.

In Nuxt.js, instead of using the Vue.use() function, you simply create a new file in the plugins folder and inject your Vue plugin into the Vue instance using the nuxt.config.js file.

8. Static

The static folder contains all the static files in your project that will likely not change or that should be rendered without any compilation on it.

All the files included in the static directory will automatically be served by Nuxt.js and accessible through your project root URL.

This directory is excellent for files such as favicon, robots.txt, etc.

9. Store

The store directory contains all your Vuex store files, and it is split into modules by default.

The Vuex store comes out of the box but is disabled by default. You need to activate the store by creating an index.js file inside the store directory.

A Vuex store is necessary when creating and managing an enterprise project. That’s why Nuxt.js comes prebuilt with Vues store and is configured to accommodate enterprise-level application development.

Nuxt.js Pages and Routing System

Nuxt.js makes the routing system as easy as creating directories and files in the pages directory. It automatically generates a router file based on the files and folder structure of that directory.

For instance, if you have an about.vue file in the pages directory, it will automatically convert the route, and you can then visit the route on your browser to see the contents of the “About” page.

This routing system also allows you to define three different routes by only creating files and folders. Let’s explore these route types in more detail.

1. Basic Routing

Basic routing is those routes that do not require any additional configurations for them to work. It’s the simplest type of routing and can be as plain as /about, /contact, etc.

To create a basic routing system, you can structure your pages directory like the below:

pages/
--| services.vue
--| contact.vue
--| index.vue

Nuxt.js will generate a router file using the files you added in the pages directory automatically:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: ‘services’,
      path: '/services’,
      component: 'pages/services’
    },
    {
      name: 'contact',
      path: '/contact',
      component: 'pages/contact'
    },
  ]
}

Now all our files are neatly structured and automatically routed.

2. Nested Routing

Nested routes are routes that are created within a parent route. Nested routes are used to create multiple levels of deep routing.

To create nested routes, create a parent folder and place all the route files within that folder.

Let’s try out creating a nested route:

pages/
 --| dashboard/
 -----| user.vue
 -----| settings.vue
 --| dashboard.vue
 --| services.vue
 --| contact.vue
 --| index.vue

In the folder structure above, we created a new file and folder with the same name as the dashboard, and next, we added a user.vue and settings.vue files as the children of the dashboard folder.

This simple folder structure will generate a router with routes similar to the one below:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'services',
      path: '/services',
      component: 'pages/services'
    },
    {
      name: 'contact',
      path: '/contact',
      component: 'pages/contact'
    },
    {
      name: 'dashboard',
      path: '/dashboard',
      component: 'pages/dashboard.vue',
      children: [
        {
          name: 'dashboard-user',
          path: '/dashboard/user',
          component: 'pages/dashboard/user.vue'
        },
        {
          name: 'dashboard-settings',
          path: '/dashboard/settings',
          component: 'pages/dashboard/settings.vue'
        }
      ]
    }
  ]
}

Nested routes are a bit cumbersome to create in Vue.js especially if you have to create plenty of it as you can see in the code sample above, but Nuxt.js made it simple and easy by only creating Vue files in a nested folder.

3. Dynamic Routing

Dynamic routes are created with unknown routes either because it depends on an API call or you don’t want to create the page repeatedly. These are routes that are defined from a variable either a name, number or ID retrieved from client data on the app.

This is useful when building a news app for example, where you don’t know the ID or slug of the post the user is going to click on to read. But with the dynamic route, you can retrieve the ID/slug of the post and render the correct post with the ID/slug.

To create a dynamic route, you add an underscore to the .vue file or directory name. You can name the file or directory any name of your choice, but an underscore must be attached to make it dynamic.

For instance, if you define a _slug.vue file in the pages directory, you can access the value using params.slug object. We’ll demonstrate with an example how to create a dynamic route:

pages/
--|user/
-----| index.vue
-----| about.vue
-----| _routeName
-------| index.vue
-------| info.vue
--| dashboard/
-----| user.vue
-----| settings.vue
--| dashboard.vue
--| services.vue
--| _id.vue
--| contact.vue
--| index.vue

Appending the underscore to _id and _routeName will create a dynamic route for the page with ID param, along with a parent route with a string param with the above children routes. This page structure will generate a router with the following routes within the file:

   {
      name: 'work',
      path: '/work',
      component: 'pages/work'
    },
    {
      name: 'contact',
      path: '/contact',
      component: 'pages/contact'
    },
    {
      name: 'id',
      path: '/:id',
      component: 'pages/_id.vue'
    }
    {
      name: 'user',
      path: '/user',
      component: 'pages/user/index.vue'
    },
    {
      name: 'user-about',
      path: '/user/about',
      component: 'pages/user/about.vue'
    },
    {
      name: 'user-routeName',
      path: '/user/:routeName',
      component: 'pages/user/_routeName/index.vue'
    },
    {
      name: 'user-routeName-info',
      path: '/user/:routeName/info',
      component: 'pages/user/route.vue'
    },
    {
      name: 'dashboard',
      path: '/dashboard',
      component: 'pages/dashboard.vue',
      children: [
        {
          name: 'dashboard-user',
          path: '/dashboard/user',
          component: 'pages/dashboard/user.vue'
        },
        {
          name: 'dashboard-settings',
          path: '/dashboard/settings',
          component: 'pages/dashboard/settings.vue'
        }
      ]
    }
  ]
}

Now that we’ve explored the different routing systems that come built into the Nuxt.js framework, let’s learn how to create and manage Vuex stores.

Using Vuex Store in Nuxt.js

Nuxt.js solves a major Vue structure problem by streamlining how Vuex is handled when building an enterprise project. The store folder is automatically built when creating a new application.

You can activate the Vuex store by creating an index.js file inside the store folder. With this simple improvement, the Vuex store is now structured and moduled using best practices outlined in the official Vuex documentation, which encourages large-scale application development.

Your index.js file should contain the following structure to correspond to how Nuxt.js structures your Vuex store. Let’s take a look:

export const state = () => ({
  
})
export const getters = {

}
export const mutations = {
  
}
export const actions = {
  
}

Nuxt.js allows you to use the split-by-feature approach in your large-scale application. With this approach, you create different Vuex store files to correspond to the features you have in your applications. For instance, if your application has users, posts, and comments features, you can create these different files such as users.js, posts.js, and comments.js in your store directory.

This method makes it easy to access a particular store file based on the feature of the application, transforming the tedious process of locating and updating data into an effortless walk in the park.

Summary

Nuxt.js is a very popular SSR and statically generated frontend Vue framework. It doesn’t only solve the problem of configuring and setting up SSR in Vue applications — it also boosts the development of enterprise applications by adhering to best practices in structuring and architecting large-scale Vue applications.

This guide explored everything you need to know about Nuxt.js, including what you can build with it. We discussed static-generated pages, single-page applications (SPAs), and Universal applications, along with how to develop them using Nuxt.js.

You’ve now seen for yourself just how easy and beneficial it can be to choose Nuxt.js for your next large enterprise project. Let us know in the comment section what you will be building with these new superpowers!