Skip to content

Nuxt.js

Author: Marte M.K. <Martekn>

Introduction

Nuxt.js is a meta-framework, which means it’s built on top of another framework - Vue.js. Essentially, it provides extra features to make working with Vue.js both easier and more powerful.

There’s also a huge variety of rendering modes such as Single Page Application (SPA), Server-side rendering (SSR), Universal rendering, Static Generated Pages and more to choose from when using Nuxt.js. We will go over several rendering modes later and see how they work.

In addition to offering various rendering modes, Nuxt.js also improves the developer experience with features like auto-imports, file-based routing, and out-of-the-box TypeScript support.

Brief History

  • 2016 - The initial version 0.0.1 of Nuxt.js was released
  • 2018 - The first major release, Nuxt 1.0.0. This introduced features such as custom layouts, middleware and various rendering modes.
  • 2018 - Nuxt.js 2.0.0 release
  • 2020 - Full static site generation capabilities were introduced
  • 2021 - Vite support was added
  • 2021 - Nuxt 3.0.0 beta was released providing a more modular architecture and improved performance.
  • 2022 - Nuxt 3.0.0 was officially released

Main Features

As this is a meta-framework built on top of Vue.js it does offer all the benefits and features of a traditional Vue.js project but Nuxt.js has several nice features to offer in addition to those.

Rendering modes

Nuxt.js provides multiple rendering options to fit different project requirements and needs.

Single Page Application (SPA)

A traditional Vue.js application uses the Single Page Application approach. This means that the page renders entirely on the client-side using JavaScript. In this approach the server will send and almost empty HTML file to the browser, which links to a JavaScript file. The page then renders once that JavaScript file is parsed and rendered.

This approach is supported by Nuxt.js and is a great option for web apps that don’t require content to rank high on SEO and/or there’s no need for cards on social platforms.

Server-side rendering (SSR)

Server-side rendering or SSR renders the content on the server. This means that the HTML file sent to the browser includes all the HTML markup for that page. This lets the content be crawled and indexed by the search engines and will improve the experience of sharing pages on social media. In addition to this, it also does provide a small performance boost as there’s no need to run JavaScript before the page is visible to the user.

While you can do Server-side rendering for Vue.js components without Nuxt.js, using Nuxt.js makes this a lot easier and less cumbersome.

Universal rendering

Nuxt.js takes rendering one step further with an approach called Universal rendering. This approach is essentially a mix between SSR and SPA, where you get to keep the SEO and social sharing benefits of an SRR application mixed with the interactiveness of a SPA.

When you use Universal Rendering, the server initially sends the server rendered HTML page to the browser. After this, a process called hydration happens.

Hydration is where the JavaScript file is downloading in the background. Once the file is loaded, it turns the existing HTML file into a fully interactive application that works just like a SPA.

Static site generation

Static generated pages mean there’s no external content source; it’s already embedded directly into the HTML. With Nuxt.js you can generate a static version of your site with all the benefits of SSR but for a static generated website. This lets you build powerful universal applications without a server to power the SSR benefits.

Hybrid rendering

Hybrid rendering lets you mix and match different rendering modes. This means that some pages could be using universal rendering while others could use SPA. An example of this is a content website that has an admin dashboard. The content page should be static and generated once, while the dashboard can be rendered client side.

Edge-side rendering

Edge-side rendering (ESR) allows for rendering applications closer to your users through edge servers of a Content Delivery Network (CDN). The benefit of ESR is an improved user experience through better performance and reduced latency.

Although I listed this under rendering modes, ESR is actually more of a deployment target than an actual rendering mode.

How ESR works is that when the browser sends a request for a page, instead of going to the original server, it’s intercepted by the nearest edge server. This server generates the HTML for the page and sends it back to the user. This minimizes the physical distance the data has to travel and therefore reduces the latency and will load the page faster.

Auto-imports

One feature of Nuxt.js is the auto-imports, it promises an easier experience as a developer by removing the burden of having to manage imports. It allows for auto-imported components, composables and Vue.js APIs without having to explicitly import them. It also allows auto-imports from third-party packages, which has to be configured in the nuxt.config.ts file.

Example of importing and using ref without auto-imports:

import { ref } from "vue";
const counter = ref(1);

With auto-imports, the above code no longer needs the import statement as it is automatically imported:

const counter = ref(1);

There is mixed community feedback on this feature. Some love this feature as it makes files cleaner and simplifies development. While others find that this creates edge-cases that can be troublesome to handle, and therefore chooses to disable the feature.

For more detailed information on auto-imports, check the Nuxt.js documentation

Typescript support

Nuxt.js has out of the box TypeScript support that doesn’t need any configuration to get started. This is great both for those using TypeScript but also for those who prefer JavaScript as the types bundled in the framework will provide autocompletion benefits in IDEs like VSCode.

Code splitting

Code splitting is automatically implemented in Nuxt.js. Code splitting means that the code gets split into smaller chunks or bundles, in other words it’s a way to split JavaScript code into several smaller files. The reason for doing this is to help reduce the initial load time of the application, which is especially useful for mobile devices with slow networks.

File based routing

The file system router of Nuxt.js automatically creates routes based on file names. Vue files located inside the pages/ directory create a URL/route that displays the contents of the file.

Directory Structure:

| pages/
---| about.vue
---| index.vue
---| products/
-----| [category].vue

The generated router file:

{
"routes": [
{
"path": "/about",
"component": "pages/about.vue"
}
{
"path": "/",
"component": "pages/index.vue"
},
{
"path": "/products/:category",
"component": "pages/products/[category].vue"
},
]
}

Disadvantages of Nuxt.js

As with any product, Nuxt.js has it’s disadvantages. Some commonly mentioned disadvantages are:

  • Smaller community - The community around Vue and Nuxt.js is smaller in comparison to React and Next.js. This can make finding resources and help more challenging. With a smaller community the documentation can also be lacking, as the community can often contribute to the documentation.

  • Lack of plugin and addon support - Common plugins or addons support is lacking in Nuxt.js. There are Vue plugins that work on the client-side, but only on the client-side. Some of the existing plugins may not be as well-maintained either.

  • Debugging can be painful - There’s a lot of people reporting issues with debugging when it comes to using Nuxt.js. There can be generic error messages that are unhelpful for tracking down where the issues could be. This is something that gets increasingly more difficult as the project gets more and more complex.

  • Server strain with high traffic - High traffic applications can be quite heavy on the server.

Market comparison

Next.js and SvelteKit are other meta-frameworks that are comparable to Nuxt.js. Next.js is built on top of React, while SvelteKit is built on Svelte.

They all have their own features that caters to different types of projects and requirements. This means that all of them have their place and there’s no one ‘best’ framework for all projects. You will always need to evaluate your experience with them, developer experience and project requirements to pick the optimal framework for any specific project.

Similarities

All the frameworks offer the following:

  • Typescript support
  • Server-side rendering (SSR)
  • Static site generation (SSG)
  • Code splitting
  • File based routing
  • Issues with some addon/plugin support

Performance

While all the meta-frameworks are designed to work as optimally and quickly as they can at a base level, SvelteKit takes performance a bit further than Next.js and Nuxt.js. SvelteKit is quite known for it’s performance benefits which it achieves in several ways such as only loading the needed code or compiling code to vanilla JavaScript at build time. All of this helps reduce load time and smaller app sizes.

Learning curve

Due to these meta-frameworks being built on other frameworks we have to look at the learning curve of both the meta-framework itself and the framework it’s built on.

The learning curve for Next, Nuxt and SvelteKit will be smaller if you know the framework that it’s built on. However, if you are completely new to it, it will make it more challenging to get started. React might be the most difficult framework to learn in comparison to Vue and Svelte despite having a larger community to learn from. Both Vue and Svelte is often referred to as easier frameworks to learn, especially Svelte is highly praised for its simple syntax and minimal boilerplate.

For the meta-frameworks themselves, Nuxt.js is designed to be intuitive for developers experienced with Vue.js. It provides a lot of built-in configurations and conventions making development a streamlined experience. However there are some concepts that can take a fair about of time to learn and master. Next on the other hand has fewer concepts, with more resources to learn from. When it comes to SvelteKit, it’s often said it has a smoother learning curve than most other meta-frameworks.

Community size

React has a massive community compared to Vue and Svelte, and Next.js is one of the most popular frameworks for React. This means that the community for Next.js is also quite large and has a lot more resources available compared to Nuxt.js and SvelteKit.

As mentioned Nuxt has a smaller community than Next, which comes with it’s drawbacks. The same can be said for SvelteKit which has an even smaller community than Nuxt.js. SvelteKit and Svelte is growing quite rapidly and has been gaining a lot of attention due to it’s simplicity and performance.

Getting Started

To get started using Nuxt.js you need to have Node.js version 18.0.0 or newer installed.

To install, open the terminal and navigate to where you want to setup your project folder. Then run the following command in the terminal to initialize a Nuxt.js project:

Terminal window
npx nuxi@latest init <project-name>

Then open the new project folder in your IDE and run the following command in the terminal to start the application in development mode:

Terminal window
npm run dev -- -o

The -o flag will automatically open your browser to the running development server.

For more information on how to configure and understand the Nuxt setup please check the official documentation

Summary

Nuxt.js is a powerful meta-framework built on top of Vue.js, offering multiple rendering modes like SPA, SSR, Universal rendering, and static site generation. It aims to improve the developer experience through features like auto imports, zero-config typescript support and file-based routing. While Nuxt.js has some disadvantages, such as the smaller community and plugin limitations compared to Next.js or it’s not as performant as SvelteKit, it provides a good developer experience for projects needing server-side rendering.

References

Additional Resources