Telerik blogs
Vue

Nuxt.js is a universal framework built on Vue.js, Vue Router, Vuex, Vue Server Renderer and vue-meta plugins in other to provide a rich toolset that can build any type of web application.

It is called a universal framework because it was built to be flexible enough that you can use it for any project ranging from Static Sites to Single Page Applications.

Its main focus is on the UI Rendering aspect of development while trying to abstract away the client/server distribution.

What Makes Nuxt.js Special?

  1. Vue Powered: Nuxt.js is built on Vue.js, hence allows you to write Vue apps at its core, which means all the added advantages of Vue exist here. As a matter of fact, Nuxt.js was built to enable you to write your best version of Vue.js code.
  2. Automatic Route Handling: Nuxt.js uses Vue-router to handle routes but automatically generates the configuration/routes needed based off the Vue file structures in the pages folder. This means you don't have to ever bother about setting up Vue-router configuration because Nuxt will do that for you.
  3. Server-Side Rendering: Nuxt.js uses the Vue Server Renderer plugin to handle server-side rendering but, as usual, encapsulates all that hard work and handles this automatically while also providing properties that can be used to easily modify meta tags for individual, all or even dynamic pages.
  4. Static Sites: Nuxt.js has a nuxt generate command, that generates the HTML static version of your application for each page in your routes and stores them in a file, which you can host on any static hosting platform.
  5. Webpack Powered: Nuxt.js under the hood uses webpack with vue-loader and babel-loader to bundle, minify, transpile ES6/ES7 and code-split your code. Nuxt.js has got you covered all around.
  6. HTTP/2: Nuxt.js provides us with a property that can activate HTTP/2 push headers in our application. HTTP/2 Push is a feature that lets a server push resources to the client without a corresponding request (i.e. no immediate request for that resource).
  7. Hot Module Replacement in Development: Thanks to webpack and the vue-loader, Nuxt.js updates the view for changes made to the code while the application is running, without requiring a full page reload.

Installing Nuxt.js

Nuxt.js team created a project starter template for the Vue CLI 3, which they say is the starter project template without the distraction of a complicated development environment that enables you use the Vue CLI to build start a Nuxt.js Project.

The template is built for the Vue CLI, so you have to install that first if you don't already have it installed.

To install the Vue CLI, fire up your terminal and run the below:

$ npm install -g @vue/cli @vue/cli-init

Next, install the template and use that to generate a new project:

$ vue init nuxt-community/starter-template <project-name>

Once the installation is done and the project has been created, change directory into the new project folder created and install all the dependencies.

$ cd <project-name>
$ npm install

Finally, when that is done, we launch the project with npm run dev. The application should successfully be running at localhost:3000.

Folder Structure

If we take a look at our new project, we notice some folders/files have been created already; they are intended to provide us with a great starting point for our applications.

Let's do a quick dive into what each folder is for and what is meant to be inside.

  • Assets: This is where all our asset files, such as images, stylesheet and any other asset that our application might need, would exist.
  • Components: Contains reusable components that would be used in our application (e.g. Buttons, Inputs, sidebars, etc.).
  • Layouts: This folder will house our application layouts which will be reused across the board in our application. Note: This folder cannot and should not be renamed.
  • Middleware: Like the name implies, it contains our application's middleware. Middleware is functions that you require to run before a component is rendered (e.g. check if a user is signed in before displaying a page).
  • Pages: This folder contains our application's views and routes since Nuxt.js reads all the files inside this folder and automatically creates our application routes based off this view files. This folder also can't be renamed.
  • Plugins: This houses all our JavaScript plugins that need to run before our root Vue.js Application is instantiated.
  • Static: It's very similar to the Assets folder, only the Assets folder is meant for files that need to be parsed by webpack (i.e. files that need some kind of compilation [SASS → CSS] or processing), while the Static folder is for files or assets that have already been processed or are in their final state.

Adding Assets

Thanks to webpack, vue-loader, file-loader and url-loader, Nuxt.js has simplified the way we link to assets in our project folder.

To link to files that are in the assets folder, you would need to add ~/ before the Assets folder name as below:

<img src="~/assets/image.png" />

But if you want to link to files that are in the Static folder, you will just link to them as if these files exist in the root directory by using /:

<img src="/image.png" />

You might be wondering why.

Well, files in the Assets folder require the character, ~ mainly because by default the Vue-loader plugin in webpack would resolve the files as module dependencies, and ~ is just an alias telling Vue-loader where the Assets folder is.

One of the cool parts about parsing assets with the Vue-loader is that it also helps with handling versioning of assets for better caching, while at the same time, if any of the assets are less than 1KB in size, they get inlined as base-64 data to reduce the number of HTTP requests for these smaller files.

The Static folder on the other hand is automatically served by Nuxt, and it's moved into the project's root when building for production.

<!-- image in the static folder -->
<img src="/image.png" />

<!-- image in the assets folder -->
<img src="~/assets/image-2.png" />

Components

Components are reusable Vue instances with a name. When we create a page in Nuxt, we create a component, and each of these components has functions that make it work. Nuxt.js introduces some extra functions, attributes or methods, as the case may be, to provide more features to help suit development of said components.

  • asyncData: The asyncData hook allows you to fetch data needed for a page to be rendered on the server just before it's actually rendered on the client. This enables your page to always have content when, say, the Google indexer is trying to index your page — the asyncData hook provides it with data.
  • fetch: This method handles interaction with the store. It allows you the liberty of providing data to the Vuex store even before the component is rendered on the view. This is perfect for when another component needs data from say another component before said component is rendered.
  • loading: Nuxt.js provides a loading state in the app, and this method allows you to interrupt the loading state and manually control it.
  • layout: This sets which layout from the layouts directory should be used in a component.
  • transition: Allows you to set specific transitions for the page component.
  • scrollToTop: This method allows you to specify if you would like the page to automatically scroll to the top before rendering the page.
  • validate: The validate hook allows you create a validator method that checks what kind of parameter is passed in a dynamic routes slug. This is useful for when you would want to ensure it's a number that is passed into the slug not a string, or vice versa.
  • middleware: Allows you specify the middleware for that component.

Routing

Routing in Nuxt.js is very interesting. It looks at the file structure in your Pages folder and automatically decides on the route configurations based off that structure. All you have to do is structure your Pages folders the way you would want the URLs to be, and Nuxt.js does all the magic under the hood.

It makes use of the Vue Router plugin to generate routes; hence, the configuration generated is the same as the one you already know if you use Vue Router in your Vue.js applications.

There's a little twist though: Instead of using <router-link> like you would normally do, you would use <nuxt-link>.

Nuxt.js would also handle a 404 page request error, like when a page or route isn't available and the user navigates to it. Nuxt has a default 404 page but also provides you with ways to customize or use your own 404 page design.

Now, let's dive into some examples, as I am sure you're already wondering how you would handle things like Dynamic Routes, etc.

Basic Routes

A basic folder structure would be one that has a folder and then other view files inside, like below:

pages/
--| work/
-----| index.vue
-----| progress.vue
-----| telerik.vue
--| index.vue

Nuxt would generate the below for the basic folder structure above:

router: {
  routes: [
    { name: 'index', path: '/', component: 'pages/index.vue' },
    { name: 'work', path: '/work', component: 'pages/user/index.vue' },
    { name: 'work-progress', path: '/work/progress', component: 'pages/work/progress.vue' },
    { name: 'work-telerik', path: '/work/telerik', component: 'pages/work/telerik.vue' }
  ]
}

Dynamic Routes

Dynamic routes are routes that take in dynamic parameters in their URLs. To do this, we would have to prefix the name of our .vue file or folder with an underscore.

pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue

The above becomes:

router: {
  routes: [
    { name: 'index', path: '/', component: 'pages/index.vue' },
    { name: 'users-id', path: '/users/:id?', component: 'pages/users/_id.vue' },
    { name: 'slug', path: '/:slug', component: 'pages/_slug/index.vue' },
    { name: 'slug-comments', path: '/:slug/comments', component: 'pages/_slug/comments.vue' }
  ]
}

Nested Routes

pages/
--| work/
-----| _id.vue
-----| index.vue
--| work.vue

The above would generate:

router: {
  routes: [
    {
      path: '/work',
      component: 'pages/work.vue',
      children: [
        { path: '', component: 'pages/work/index.vue', name: 'work' },
        { path: ':id', component: 'pages/work/_id.vue', name: 'work-id' }
      ]}
  ]
}

Setting Page Meta Tags

Nuxt.js provides us with properties that enable us update the headers, meta and HTML attributes of a page. It uses vue-meta behind the scenes to do all this great work.

To set the head elements, such as meta and link, in a page's components you would have to use the head attribute provided by nuxt.js in the page's component.

<template>
  <section class="container">
    <div>
      <h1 class="title">Nuxt.js Page</h1>
    </div>
  </section>
</template>

<script>
  export default {
    head: {
      meta: [
        { charset: 'utf-8' },
        { name: 'viewport', content: 'width=device-width, initial-scale=1' }
      ],
      link: [
        { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Open+Sans' }
      ]
    },
    data() {
      return { }
    }
  }
</script>

Customizing the Error Page

Nuxt.js by default has its own error page configured, but it also allows you to specify your own custom error page.

All you need to do is go into the layouts folder and create a vue component called error.vue and, boom: anytime there's a 404 or 500 error, Nuxt presents the new error page to the client.

Deploying Nuxt.js Apps

Depending on what you're trying to build, there are three different modes that can be used to prepare our application for production.

Server Rendered

To build your application, all you have to do is run the code below;

$ npm run build

This command essentially dives into our code, analyzes, generates the routes, compiles the files that need compiling, and then creates a folder named .nuxt and moves over all these production-prepared files.

Now we should have a fully server side rendered Vue.js Application. Yeah, it's a Vue.js app.

Static Site Generated

To generate our application into static files, we would have to run the command below:

$ npm run generate

This command compiles our code, generates the routes and inlines all the URLs in each of the static pages generated and stores them in a dist folder.

Single Page Application

Generating a single page application with nuxt.js can be done in two ways.

  1. add mode, 'spa' to the nuxt.config.js
  2. add --spa flag to your scripts in package.json
"scripts": {
  "dev": "nuxt --spa",
  "build": "nuxt build --spa",
  "start": "nuxt start",
  "generate": "nuxt generate",
  "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
  "precommit": "npm run lint"
}

And, there you have it! You're good to go.


More Vue Info: Want to learn about creating great user interfaces with Vue? Check out Kendo UI for Vue with everything from grids and charts to schedulers and pickers.


Nosa Obaseki
About the Author

Nosa Obaseki

Nosa is a Frontend Developer with a passion for turning designs into beautiful interactive interfaces.

Related Posts

Comments

Comments are disabled in preview mode.