| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
 | import Link from '@components/atoms/links/link';
import { settings } from '@utils/config';
import Script from 'next/script';
import { FC } from 'react';
import { useIntl } from 'react-intl';
import { BreadcrumbList, ListItem, WithContext } from 'schema-dts';
import styles from './breadcrumb.module.scss';
export type BreadcrumbItem = {
  /**
   * The item id.
   */
  id: string;
  /**
   * The item URL.
   */
  url: string;
  /**
   * The item name.
   */
  name: string;
};
export type BreadcrumbProps = {
  /**
   * Set additional classnames to the nav element.
   */
  className?: string;
  /**
   * Set additional classnames to the breadcrumb items.
   */
  itemClassName?: string;
  /**
   * The breadcrumb items
   */
  items: BreadcrumbItem[];
};
/**
 * Breadcrumb component
 *
 * Render a breadcrumb navigation.
 */
const Breadcrumb: FC<BreadcrumbProps> = ({
  itemClassName = '',
  items,
  ...props
}) => {
  const intl = useIntl();
  const ariaLabel = intl.formatMessage({
    defaultMessage: 'Breadcrumb',
    description: 'Breadcrumb: an accessible name for the breadcrumb nav.',
    id: '28nnDY',
  });
  /**
   * Retrieve the breadcrumb list items.
   *
   * @param {BreadcrumbItem[]} list - The breadcrumb items.
   * @returns {JSX.Element[]} The list items.
   */
  const getListItems = (list: BreadcrumbItem[]): JSX.Element[] => {
    return list.map((item, index) => {
      const isLastItem = index === list.length - 1;
      const itemStyles = isLastItem
        ? `${styles.item} screen-reader-text`
        : styles.item;
      return (
        <li key={item.id} className={`${itemStyles} ${itemClassName}`}>
          {isLastItem ? item.name : <Link href={item.url}>{item.name}</Link>}
        </li>
      );
    });
  };
  /**
   * Retrieve the breadcrumb list items with Schema.org format.
   *
   * @param {BreadcrumbItem[]} list - The breadcrumb items.
   * @returns {ListItem[]} An array of list items using Schema.org format.
   */
  const getSchemaItems = (list: BreadcrumbItem[]): ListItem[] => {
    const schemaItems: ListItem[] = [];
    list.forEach((item, index) => {
      schemaItems.push({
        '@type': 'ListItem',
        position: index + 1,
        name: item.name,
        item: item.url,
      });
    });
    return schemaItems;
  };
  const schemaJsonLd: WithContext<BreadcrumbList> = {
    '@context': 'https://schema.org',
    '@type': 'BreadcrumbList',
    '@id': `${settings.url}/#breadcrumb`,
    itemListElement: getSchemaItems(items),
  };
  return (
    <>
      <Script
        id="schema-breadcrumb"
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
      />
      <nav aria-label={ariaLabel} {...props}>
        <span className="screen-reader-text">
          {intl.formatMessage({
            defaultMessage: 'You are here:',
            description: 'Breadcrumb: You are here prefix',
            id: '16zl9Z',
          })}
        </span>
        <ol className={styles.list}>{getListItems(items)}</ol>
      </nav>
    </>
  );
};
export default Breadcrumb;
 |