How to disable Nuxt's progress bar for specific pages?
Tags: nuxt, vue
Published: 2020-01-31 23:42:48

Nuxtjs has a global progress bar that shows up while navigating between two routes. It is fully customizable. Its color, height, size, and duration can be easily changed using Nuxt's config file. Take a look at Nuxt's [documentation](https://nuxtjs.org/api/configuration-loading/#customizing-the-progress-bar).
If the progress bar's default style does not fit your application, you can simply create a loading component and tell Nuxt to load your component instead of the default progress bar.
```js
export default {
  loading: '~/path/to/custom-loading-component.vue',
}
```
Custom components should have two methods start and finish. Before every route change, Nuxt calls the start function of component and after the new page is completely loaded, the finish function is called. Take a look at [official documentation](https://nuxtjs.org/api/configuration-loading/#using-a-custom-loading-component)
Nuxt's loading bar is awesome and handy, but it has limitations in controlling its visibility. The progress bar can be disabled for all the pages or none of the pages, there isn't any config to customize the progress bar's visibility for a specific page. But nothing is impossible, especially in Nuxt. It takes a couple of hours to find a solution.
In order to disable loading bar to a specific page, you need three things:
### Global flag to control the progress bar's visibility.
Create a boolean property in `store/index.js`
```js
export const state = () => ({
  routerLoadingEnable: true
})
export const mutations = {
  setRouterLoadingEnable (state, payload) {
    state.routerLoadingEnable = payload
  }
}
```
### Global mixin
Create a global mixin to register `beforeRouteLeave` hook for each page in order to modify the control flag. Create and register a plugin in `nuxt.config.js`
```js
export default {
  plugins: [
    '~/plugins/loading-brain',
  ]
}
```
Inside `plugins/loading-brain.js` register global mixin and implement `beforeRouteLeave` hook.
```js
import Vue from 'vue'
const disabledPages = [
  '/trips',
  '^/$', // exact match for homepage
  '/profile/.*'
].map(r => new RegExp(r))
Vue.mixin({
  beforeRouteLeave (to, from, next) {
    if (disabledPages.find(p => p.test(to.path))) {
      this.$store.commit('setRouterLoadingEnable', false)
    }
    next()
  }
})
```
### Custom loading component
Create a custom component for loading, to show loading based on control flag in `components/loading.vue`
```vue
<template lang="html">
  <div class="loading-page" v-if="loading">
    <p>Loading...</p>
  </div>
</template>

<script>
export default {
  data: () => ({
    loading: false
  }),
  methods: {
    start () {
      if (this.$store.state.routerLoadingEnable === true) {
        this.loading = true
      }
    },
    finish () {
      this.loading = false 
      this.$store.commit('setRouterLoadingEnable', true)
    }
  }
}
</script>

<style scoped>
.loading-page {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.8);
  text-align: center;
  padding-top: 200px;
  font-size: 30px;
  font-family: sans-serif;
}
</style>
```
At the end, update `nuxt.config.js` to tell Nuxt to use our component.
```js
export default {
  loading: '~/components/loading.vue'
}
```