DEV Community

loading...
Cover image for How to disable Nuxt's progress bar for specific pages?

How to disable Nuxt's progress bar for specific pages?

farnabaz profile image Ahad Birang ・2 min read

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

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

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

export default {
  plugins: [
    '~/plugins/loading-brain',
  ]
}

Inside plugins/loading-brain.js register global mixin and implement beforeRouteLeave hook.

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

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

export default {
  loading: '~/components/loading.vue'
}

Discussion (0)

pic
Editor guide