harlan-zw / nuxt-seo

The complete SEO solution for Nuxt.
https://nuxtseo.com
MIT License
1.05k stars 67 forks source link

useBreadcrumbItems() generated invalid JSON-lD #275

Closed remihuigen closed 2 months ago

remihuigen commented 3 months ago

Describe the bug

The composable useBreadcrumbItems() generates invalid JSON-lD, according to schema.org validation tool and the given examples of BreadcrumbList

See for example https://dev.traineesinonderwijs.nl/activiteiten/startweek-traineegroep-2024/ , which uses Nuxt UI component <UBreadcrumb />

The JSON-LD that's generated by useBreadcrumbItems() for this page is

{
    "id": "#breadcrumb",
    "itemListElement": [
      {
        "name": "Home",
        "item": "https://traineesinonderwijs.nl/",
      },
      {
        "name": "Activiteiten",
        "item": "https://traineesinonderwijs.nl/activiteiten/",
      },
      {
        "name": "Startweek traineegroep 2024",
        "item": "https://traineesinonderwijs.nl/activiteiten/startweek-traineegroep-2024/",
      }
    ]
}

These are missing the @type prop. So it should be 👇

{
    "@type": "BreadcrumbList",
    "id": "#breadcrumb",
    "itemListElement": [
      {
        "name": "Home",
        "item": "https://traineesinonderwijs.nl/",
        "@type": "ListItem"
      },
      {
        "name": "Activiteitan",
        "item": "https://traineesinonderwijs.nl/activiteiten/",
        "@type": "ListItem"
      },
      {
        "name": "Startweek traineegroep 2024",
        "item": "https://traineesinonderwijs.nl/activiteiten/startweek-traineegroep-2024/",
        "@type": "ListItem"
      }
    ]
}

But maybe I'm just using the composable the wrong way. My implementation in Crumbs.vue component 👇

<template>
  <UBreadcrumb :links="links" class="mb-4 md:mb-6 -mt-6 md:-mt-4 z-20" />
</template>

<script setup lang="ts">
const props = defineProps<{
  /** Used to overide current page title */
  title?: string;
  /** Used to override parents in route structure (not the current page itself) */
  parentOverrides?: any[];
}>();
const overrides = computed(() => {
  if (!props.parentOverrides && !props.title) return null;
  const crumbs = props.parentOverrides || [undefined, undefined];
  if (!!props.title) {
    crumbs.push({
      label: props.title,
    });
  }
  return crumbs;
});

const options = computed(() => {
  let options: any = {
    schemaOrg: true,
  };

  if (overrides.value) options.overrides = overrides.value;

  return options;
});

const links = useBreadcrumbItems(options.value);
</script>

Reproduction

No response

System / Nuxt Info

"nuxt": "^3.12.3", "@nuxtjs/seo": "^2.0.0-rc.15"

harlan-zw commented 2 months ago

Hey! Thanks for reporting this, looks like it's fixed in v2.0.0-rc.16.

Let me know if you have any issues with it.