Index
About
Installation
Directory Structure
Routing
asyncData
VuexStore
Using External CDN
Deploy on Heroku
Nuxt.js
Nuxt.js is a higher-level framework that builds on top of Vue Js. It simplifies the development of universal or single page Vue Js apps.
Layman - it solves SSR ( Server Side Rendering ) in a much efficient manner along with many other extra benefits :-
- Its default scaffolding is a bit better & organised than Vue cli
- It even gives options to Choose between any server-side frameworks, UI framework, testing framework, axios, & what not
- It simplifies routing in a Vuejs app simply by putting .vue files in pages folder ( created by default )
- It make Vuejs app SEO friendly by pre-rendering pages on server, which is not so easy in Vuejs itself
- It can create universal app which is used to describe JavaScript code that can execute both on the client and the server side.
Installation
npx create-nuxt-app
once you open the project in you code editor ( here I’m using Visual Studio Code ) you will see something like this
Directory Structure
Assets
The assets
directory contains your un-compiled assets such as Stylus or Sass files, images, or fonts.
Components
The components
directory contains your Vue.js Components.
Layouts
The layouts
directory includes your application layouts. Layouts are used to change the look and feel of your page (for example by including a sidebar, navbar, footer, etc).
Middleware
The middleware
directory contains your Application Middleware. Middleware lets you define custom functions that can be run before rendering either a page or a group of pages (layouts).
Pages
The pages
directory contains your Application Views and Routes. The framework reads all the .vue
files inside this directory and creates the application router.
Note: This directory cannot be renamed without extra configuration.
Plugins
The plugins
directory contains your Javascript plugins that you want to run before instantiating the root Vue.js Application. This is the place to register components globally and to inject functions or constants.
Static
The static
directory is directly mapped to the server root (/static/robots.txt
is accessible under http://localhost:3000/robots.txt
) and contains files that likely won’t be changed (i.e. the favicon)
Example**:** /static/robots.txt
is mapped as /robots.txt
Note: This directory cannot be renamed without extra configuration.
Store
The store
directory contains your Vuex Store files. The Vuex Store comes with Nuxt.js out of the box but is disabled by default. Creating an index.js
file in this directory enables the store.
Note: This directory cannot be renamed without extra configuration.
Routing in Nuxt Js
Although Nuxt Js automatically generates router configuration based on the file structure in the pages directory you can simply add .vue files in pages directory & Nuxt Js will automatically configure them as route
To navigate between pages, Nuxt Js recommends <nuxt-link to="/">Home</nuxt-link>
Basic routing in Nuxt Js like:-
index.vue and one.vue will be compiled by nuxt as :-
router: {
routes: [
{ name: 'user',
path: '/user',
component: 'pages/user/index.vue'
},
{ name: 'user-one',
path: '/user/one',
component: 'pages/user/one.vue'
}
]
}
& on the right side you can see the simple implementation of the same using
Async Data
As the vanilla vuejs has data() Nuxtjs has async data() which gives the same result ( asyncData() override the results from data()), basically it is called on the server side once in order to fetch / pre-render data & will be called every time whenever the component would be called.
Nuxt Js offers different approach to access asyncData
Returning a promise
export default {
asyncData ({ params }) {
return axios.get(`https://my-api/posts/${params.id}`)
.then((res) => {
return { title: res.data.title }
})
}
}
Using async/await
export default {
async asyncData ({ params }) {
let { data } = await axios.get(`https://my-api/posts/${params.id}`)
return { title: data.title }
}
}
Using Vuex Store in Nuxt Js
Lets make a simple todo-list & use Vuex Store to store data, we need to add todoApp.vue in pages directory so that we can access it from browser URL
will use module based store mode, for module based we need to make a index.js file inside store directory store/index.js
export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
then will create a new module in store directory store/todos.js
export const state = () => ({
list: []
})
export const mutations = {
add(state, text) {
state.list.unshift({
text: text,
number: Math.floor(Math.random() * 6) + 1,
done: false
})
},
markDone(state, status) {
if (status.mark === 'mark') {
state.list[status.index].done = !state.list[status.index].done
state.list[status.index].number = 0
} else if (status.mark === 'unmark') {
state.list[status.index].done = !state.list[status.index].done
state.list[status.index].number = Math.floor(Math.random() * 6) + 1
} else {
state.list.splice(status.index, 1)
}
},
clear(state) {
state.list = []
},
}
The store will be created as such:
new Vuex.Store({
state: () => ({
counter: 0
}),
mutations: {
increment(state) {
state.counter++
}
},
modules: {
todos: {
namespaced: true,
state: () => ({
list: []
}),
mutations: {
add(state, text) {
state.list.unshift({
text: text,
number: Math.floor(Math.random() * 6) + 1,
done: false
})
},
markDone(state, status) {
if (status.mark === 'mark') {
state.list[status.index].done = !state.list[status.index].done
state.list[status.index].number = 0
} else if (status.mark === 'unmark') {
state.list[status.index].done = !state.list[status.index].done
state.list[status.index].number = Math.floor(Math.random() * 6) + 1
} else {
state.list.splice(status.index, 1)
}
},
clear(state) {
state.list = []
}
}
}
}
})
now that store has been made & compiled by NuxtJs time to access store modules
import { mapMutations } from 'vuex'
export default {
name: 'todoApp',
computed: {
items() {
return this.$store.state.todos.list
}
},
data() {
return {
text: ''
}
},
methods: {
...mapMutations({
toggle: 'todos/toggle' // mutations example
}),
add() {
this.text.trim()
if (!this.text.length) {
return
}
this.$store.commit('todos/add', this.text)
setTimeout(
that => {
that.text = ''
},
100,
this
)
},
markDone(i, mark) {
const status = { index: i, mark: mark }
this.$store.commit('todos/markDone', status)
},
clear() {
this.$store.commit('todos/clear')
}
}
}
Using External CDN in Nuxt Js
Nuxt Js basic scaffolding do not have any index.html file like we do in vuecli, so in order to add CDN or maybe link some external CSS we need to look for nuxt.config.js which will be available on the root of the app directory itself
Deploy your Nuxt Js SSR
In order to deploy your app we need a server, for demonstration I am using heroku.
Lets create a new app on heroku first which is pretty straightforward, then add heroku remote to your existing git repo
Then we need to add Config Vars to the heroku app in order to run Nuxt Js SSR app on heroku, now open heroku.com & head over to your NuxtJs app settings tab & add following config vars :-
after that, we need to add “heroku-postbuild”: “npm run build” in package.json under “scripts” object
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"heroku-postbuild": "npm run build"
}
after modifying package.json you need to run following commands:-
git add .
git commit -m ‘herokuUpload’
git push heroku master
then your app will be up & running with SSR on
Let’s see the difference between NUXT JS SSR app & VUE cli app