Nuxt.js is a universal framework created for the sole purpose of building world-class Vue.js applications that can scale. What makes Nuxt special, how do you install it, and how can you use it in your next project?
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.
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.
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.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 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 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.
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 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' }
]
}
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' }
]}
]
}
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>
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.
Depending on what you're trying to build, there are three different modes that can be used to prepare our application for production.
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.
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.
Generating a single page application with nuxt.js can be done in two ways.
nuxt.config.js
--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 is a Frontend Developer with a passion for turning designs into beautiful interactive interfaces.