How to create dynamic 'Breadcrumbs' in Nuxt.js
Asked Answered
B

4

9

Hello guys Im trying to create dynamic 'Breadcrumbs' in Nuxt.js, Does anyone have a working example how it should work

I have tried creating a simple sample but it is not working as expected, does anyone have a working solution ??

<template>
    <div class="breadcrumbs-component-wrapper">
        <b-breadcrumb class="breadcrumbs-holder">
            <b-breadcrumb-item
                v-for="(item, i) in breadcrumbs"
                :key="i"
                :to="item.name"
            >
               Test
            </b-breadcrumb-item>
        </b-breadcrumb>
    </div>
</template>

<script>
export default {
    computed: {
        breadcrumbs() {
            console.log( this.$route.matched);
            return this.$route.matched;
        },
    },
};
</script>
Bestow answered 27/8, 2019 at 14:32 Comment(2)
see github.com/pratheekhegde/vue-dynamic-breadcrumbs/blob/master/…Arras
Thanx, but I already saw that and it is not working as expected in my case :(Bestow
N
14

Here a breadcrumb component I used in old project. Feel free to adapt it to your needs. It's use buefy/bulma.

<template>
  <div class="level">
    <div class="level-left">
      <div class="level-item">
        <a class="button is-white" @click="$router.back()">
          <b-icon icon="chevron-left" size="is-medium" />
        </a>
      </div>
      <div class="level-item">
        <nav class="breadcrumb" aria-label="breadcrumbs">
          <ul>
            <li v-for="(item, i) in crumbs" :key="i" :class="item.classes">
              <nuxt-link :to="item.path">
                {{ item.name }}
              </nuxt-link>
            </li>
          </ul>
        </nav>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  computed: {
    crumbs() {
      const crumbs = []
      this.$route.matched.forEach((item, i, { length }) => {
        const crumb = {}
        crumb.path = item.path
        crumb.name = this.$i18n.t('route.' + (item.name || item.path))

        // is last item?
        if (i === length - 1) {
          // is param route? .../.../:id
          if (item.regex.keys.length > 0) {
            crumbs.push({
              path: item.path.replace(/\/:[^/:]*$/, ''),
              name: this.$i18n.t('route.' + item.name.replace(/-[^-]*$/, ''))
            })
            crumb.path = this.$route.path
            crumb.name = this.$i18n.t('route.' + this.$route.name, [
              crumb.path.match(/[^/]*$/)[0]
            ])
          }
          crumb.classes = 'is-active'
        }

        crumbs.push(crumb)
      })

      return crumbs
    }
  }
}
</script>

<style lang="scss" scoped>
/deep/ a {
  @include transition();
}
</style>

Nonna answered 28/8, 2019 at 10:0 Comment(0)
D
4

Perhaps someone will need my experience with breadcrumbs on nuxt.js + vuetify.js.

<template>
  <div class="d-inline-flex items-center" v-if="crumbs.length != 0">
    <v-tooltip bottom>
      <template v-slot:activator="{ on, attrs }">
        <v-btn
          small
          text
          plain
          fab
          v-bind="attrs"
          v-on="on"
          @click="$router.back()"
        >
          <v-icon>mdi-arrow-left</v-icon>
        </v-btn>
      </template>
      <span>Back</span>
    </v-tooltip>

    <v-breadcrumbs class="py-0" :items="crumbs"></v-breadcrumbs>
  </div>
</template>

<script>
export default {
  computed: {
    crumbs() {
      const fullPath = this.$route.fullPath
      const params = fullPath.substring(1).split('/')
      params.pop()
      const crumbs = []
      let path = ''
    
      params.forEach((param, index, { length }) => {
        path = `${path}/${param}`
        const match = this.$router.match(path)
        console.log(path)
        if (match.name !== 'index') {
          if (index === length - 1) {
            crumbs.push({
              text: path.replace(/\//g, '-').slice(1),
              disabled: true,
            })
          } else {
            crumbs.push({
              text: path.replace(/\//g, '-').slice(1),
              disabled: false,
              href: path + '/',
            })
          }
        }
      })

      return crumbs
    },
  },
}
</script>

Optionally, you can add nuxt-i18n here

<script>
export default {
  computed: {
    crumbs() {
      const fullPath = this.$route.fullPath
      const params = fullPath.substring(1).split('/')
      params.pop()
      const crumbs = []
      let path = ''
    
      params.forEach((param, index, { length }) => {
        path = `${path}/${param}`
        const match = this.$router.match(path)
        console.log(path)
        if (match.name !== 'index') {
          if (index === length - 1) {
            crumbs.push({
              text: this.$i18n.t('breadcrumbs.' + path.replace(/\//g, '_').slice(1)),
              disabled: true,
            })
          } else {
            crumbs.push({
              text: this.$i18n.t('breadcrumbs.' + path.replace(/\//g, '_').slice(1)),
              disabled: false,
              href: path + '/',
            })
          }
        }
      })

      return crumbs
    },
  },
}
</script>
Denesedengue answered 27/5, 2021 at 10:0 Comment(0)
F
3

Here it is what worked for me perfectly!

const getBreadcrumbs = () => {
  const route = useRoute()

  const pathArray = route.path.split('/')
  pathArray.shift()
  const breadcrumbs = pathArray.reduce((breadcrumbArray, path, idx) => {
    breadcrumbArray.push({
      to: !!breadcrumbArray[idx - 1]
        ? breadcrumbArray[idx - 1].to + '/' + path
        : '/' + path,
      title: path.toString().replace('-', ' '),
    })
    return breadcrumbArray
  }, [])
  return breadcrumbs
}
Fornication answered 13/9, 2022 at 9:20 Comment(1)
единственный рабочий вариант для nuxt 3Inter
A
2

I have answered this question in the Nuxt 3 : You can be inspired by it...

here is script setup code :

<script setup>
const route = useRoute();
const router = useRouter();

const crumbsRoute = computed(() => {
  let fullPath = "";
  const routes = route.fullPath.substring(1).split("/");
  return routes
    .map((route) => {
      if (route) {
        fullPath = `${fullPath}/${route}`;
        return router.resolve(fullPath);
      }
    })
    .filter(Boolean);
});
</script>

and here is template code :

<template>
  <ul class="flex items-center">
    <li
      v-for="(crumb, index) in crumbsRoute"
      :key="crumb.name"
      class="flex items-center gap-2">
      <base-icon
        icon-path="Arrow"
        svg-class="w-4"
        class="stroke-beta-gray-100"></base-icon>
      <nuxt-link
        :to="{ name: crumb.name }"
        class="text-beta-gray-150"
        :class="{ 'text-beta-gray-500': index === crumbsRoute.length - 1 }"
        >{{ crumb.meta.breadcrumbs }}</nuxt-link
      >
    </li>
  </ul>
</template>

in this method you should put breadcrumbs lable on definePageMeta() composable like this in your pages:

// in this page => localhost:3000/about-us/  
definePageMeta({
  name: "aboutUs",
  breadcrumbs: "about us",
});

so you can just add this component on everywhere you wants to :)

Aliquant answered 30/11, 2023 at 22:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.