HomeVueJSNuxt Js ( SSR on steroid )

Nuxt Js ( SSR on steroid )

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 :-

  1. Its default scaffolding is a bit better & organised than Vue cli
  2. It even gives options to Choose between any server-side frameworks, UI framework, testing framework, axios, & what not
  3. It simplifies routing in a Vuejs app simply by putting .vue files in pages folder ( created by default )
  4. It make Vuejs app SEO friendly by pre-rendering pages on server, which is not so easy in Vuejs itself
  5. 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 <project-name>

you will be asked for some questions please choose accordingly else select default
after successful installation you need to go to folder containing project & hit npm run dev to start project locally on http://localhost:3000.

once you open the project in you code editor ( here I’m using Visual Studio Code ) you will see something like this

basic scaffolding Nuxt JS provides

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 .vuefiles 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

http://localhost:3000/abouthere index.vue inside pages directory will always acts as home page & in order to access about page we just need to add “/about” in the browser URL followed host address
eg:-http://localhost:3000/about

To navigate between pages, Nuxt Js recommends <nuxt-link> component
<nuxt-link to="/">Home</nuxt-link>

Basic routing in Nuxt Js like:-

as you can see on the left in pages directory there’s a folder named user it has a two files index.vue and one.vue
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 <nuxt-link> component

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

here I’ve linked a CDN to my Nuxt Js app

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

as you can see there’s no body in this vuecli project by default that means search engine spiders would consider this website as a blank / empty page/ website

here you can see body tag is present having all front page data, search engine spiders will get to know about the page in this NUXT Js SSR app
Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: