aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/molecules/nav/breadcrumb.module.scss10
-rw-r--r--src/components/molecules/nav/breadcrumb.stories.tsx81
-rw-r--r--src/components/molecules/nav/breadcrumb.test.tsx16
-rw-r--r--src/components/molecules/nav/breadcrumb.tsx130
-rw-r--r--src/components/molecules/nav/index.ts1
-rw-r--r--src/components/organisms/nav/breadcrumbs/breadcrumbs.module.scss7
-rw-r--r--src/components/organisms/nav/breadcrumbs/breadcrumbs.stories.tsx55
-rw-r--r--src/components/organisms/nav/breadcrumbs/breadcrumbs.test.tsx22
-rw-r--r--src/components/organisms/nav/breadcrumbs/breadcrumbs.tsx66
-rw-r--r--src/components/organisms/nav/breadcrumbs/index.ts1
-rw-r--r--src/components/organisms/nav/index.ts1
-rw-r--r--src/components/templates/page/page-layout.module.scss4
-rw-r--r--src/components/templates/page/page-layout.tsx15
-rw-r--r--src/i18n/en.json12
-rw-r--r--src/i18n/fr.json12
-rw-r--r--src/utils/hooks/use-breadcrumb.ts87
16 files changed, 224 insertions, 296 deletions
diff --git a/src/components/molecules/nav/breadcrumb.module.scss b/src/components/molecules/nav/breadcrumb.module.scss
deleted file mode 100644
index 6786896..0000000
--- a/src/components/molecules/nav/breadcrumb.module.scss
+++ /dev/null
@@ -1,10 +0,0 @@
-@use "../../../styles/abstracts/placeholders";
-
-.item {
- &:not(:last-of-type) {
- &::after {
- content: ">";
- margin-left: var(--spacing-2xs);
- }
- }
-}
diff --git a/src/components/molecules/nav/breadcrumb.stories.tsx b/src/components/molecules/nav/breadcrumb.stories.tsx
deleted file mode 100644
index b6dd619..0000000
--- a/src/components/molecules/nav/breadcrumb.stories.tsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import { ComponentMeta, ComponentStory } from '@storybook/react';
-import { Breadcrumb } from './breadcrumb';
-
-/**
- * Breadcrumb - Storybook Meta
- */
-export default {
- title: 'Molecules/Navigation/Breadcrumb',
- component: Breadcrumb,
- argTypes: {
- className: {
- control: {
- type: 'text',
- },
- table: {
- category: 'Styles',
- },
- description: 'Set additional classnames to the nav element.',
- type: {
- name: 'string',
- required: false,
- },
- },
- itemClassName: {
- control: {
- type: 'text',
- },
- table: {
- category: 'Styles',
- },
- description: 'Set additional classnames to the breadcrumb items.',
- type: {
- name: 'string',
- required: false,
- },
- },
- items: {
- description: 'The breadcrumb items.',
- type: {
- name: 'object',
- required: true,
- value: {},
- },
- },
- },
-} as ComponentMeta<typeof Breadcrumb>;
-
-const Template: ComponentStory<typeof Breadcrumb> = (args) => (
- <Breadcrumb {...args} />
-);
-
-/**
- * Breadcrumb Stories - One item
- */
-export const OneItem = Template.bind({});
-OneItem.args = {
- items: [{ id: 'home', url: '#', name: 'Home' }],
-};
-
-/**
- * Breadcrumb Stories - Two items
- */
-export const TwoItems = Template.bind({});
-TwoItems.args = {
- items: [
- { id: 'home', url: '#', name: 'Home' },
- { id: 'blog', url: '#', name: 'Blog' },
- ],
-};
-
-/**
- * Breadcrumb Stories - Three items
- */
-export const ThreeItems = Template.bind({});
-ThreeItems.args = {
- items: [
- { id: 'home', url: '#', name: 'Home' },
- { id: 'blog', url: '#', name: 'Blog' },
- { id: 'post1', url: '#', name: 'A Post' },
- ],
-};
diff --git a/src/components/molecules/nav/breadcrumb.test.tsx b/src/components/molecules/nav/breadcrumb.test.tsx
deleted file mode 100644
index 8aa0d63..0000000
--- a/src/components/molecules/nav/breadcrumb.test.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import { describe, expect, it } from '@jest/globals';
-import { render, screen } from '../../../../tests/utils';
-import { Breadcrumb, type BreadcrumbItem } from './breadcrumb';
-
-const items: BreadcrumbItem[] = [
- { id: 'home', url: '#', name: 'Home' },
- { id: 'blog', url: '#', name: 'Blog' },
- { id: 'post1', url: '#', name: 'A Post' },
-];
-
-describe('Breadcrumb', () => {
- it('renders a navigation', () => {
- render(<Breadcrumb items={items} />);
- expect(screen.getByRole('navigation')).toBeInTheDocument();
- });
-});
diff --git a/src/components/molecules/nav/breadcrumb.tsx b/src/components/molecules/nav/breadcrumb.tsx
deleted file mode 100644
index 51f4633..0000000
--- a/src/components/molecules/nav/breadcrumb.tsx
+++ /dev/null
@@ -1,130 +0,0 @@
-import Script from 'next/script';
-import type { FC } from 'react';
-import { useIntl } from 'react-intl';
-import type {
- BreadcrumbList,
- ListItem as ListItemType,
- WithContext,
-} from 'schema-dts';
-import { settings } from '../../../utils/config';
-import { Link, List, ListItem } from '../../atoms';
-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.
- */
-export 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[] =>
- list.map((item, index) => {
- const isLastItem = index === list.length - 1;
- const itemStyles = isLastItem
- ? `${styles.item} screen-reader-text`
- : styles.item;
-
- return (
- <ListItem key={item.id} className={`${itemStyles} ${itemClassName}`}>
- {isLastItem ? item.name : <Link href={item.url}>{item.name}</Link>}
- </ListItem>
- );
- });
-
- /**
- * Retrieve the breadcrumb list items with Schema.org format.
- *
- * @param {BreadcrumbItem[]} list - The breadcrumb items.
- * @returns {ListItemType[]} An array of list items using Schema.org format.
- */
- const getSchemaItems = (list: BreadcrumbItem[]): ListItemType[] => {
- const schemaItems: ListItemType[] = [];
-
- 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
- dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
- id="schema-breadcrumb"
- type="application/ld+json"
- />
- <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>
- <List hideMarker isInline isOrdered spacing="2xs">
- {getListItems(items)}
- </List>
- </nav>
- </>
- );
-};
diff --git a/src/components/molecules/nav/index.ts b/src/components/molecules/nav/index.ts
index 2f9b8e3..08e47b7 100644
--- a/src/components/molecules/nav/index.ts
+++ b/src/components/molecules/nav/index.ts
@@ -1,4 +1,3 @@
-export * from './breadcrumb';
export * from './nav-item';
export * from './nav-link';
export * from './nav-list';
diff --git a/src/components/organisms/nav/breadcrumbs/breadcrumbs.module.scss b/src/components/organisms/nav/breadcrumbs/breadcrumbs.module.scss
new file mode 100644
index 0000000..1be81c4
--- /dev/null
+++ b/src/components/organisms/nav/breadcrumbs/breadcrumbs.module.scss
@@ -0,0 +1,7 @@
+.wrapper {
+ width: fit-content;
+}
+
+.sep {
+ margin-inline-start: var(--spacing-xs);
+}
diff --git a/src/components/organisms/nav/breadcrumbs/breadcrumbs.stories.tsx b/src/components/organisms/nav/breadcrumbs/breadcrumbs.stories.tsx
new file mode 100644
index 0000000..4736b26
--- /dev/null
+++ b/src/components/organisms/nav/breadcrumbs/breadcrumbs.stories.tsx
@@ -0,0 +1,55 @@
+import type { ComponentMeta, ComponentStory } from '@storybook/react';
+import { Breadcrumbs } from './breadcrumbs';
+
+/**
+ * Breadcrumbs - Storybook Meta
+ */
+export default {
+ title: 'Organisms/Nav/Breadcrumbs',
+ component: Breadcrumbs,
+ argTypes: {
+ items: {
+ description: 'The breadcrumb items.',
+ type: {
+ name: 'object',
+ required: true,
+ value: {},
+ },
+ },
+ },
+} as ComponentMeta<typeof Breadcrumbs>;
+
+const Template: ComponentStory<typeof Breadcrumbs> = (args) => (
+ <Breadcrumbs {...args} />
+);
+
+/**
+ * Breadcrumbs Stories - One item
+ */
+export const OneItem = Template.bind({});
+OneItem.args = {
+ items: [{ id: 'home', url: '#', name: 'Home' }],
+};
+
+/**
+ * Breadcrumbs Stories - Two items
+ */
+export const TwoItems = Template.bind({});
+TwoItems.args = {
+ items: [
+ { id: 'home', url: '#', name: 'Home' },
+ { id: 'blog', url: '#', name: 'Blog' },
+ ],
+};
+
+/**
+ * Breadcrumbs Stories - Three items
+ */
+export const ThreeItems = Template.bind({});
+ThreeItems.args = {
+ items: [
+ { id: 'home', url: '#', name: 'Home' },
+ { id: 'blog', url: '#', name: 'Blog' },
+ { id: 'post1', url: '#', name: 'A Post' },
+ ],
+};
diff --git a/src/components/organisms/nav/breadcrumbs/breadcrumbs.test.tsx b/src/components/organisms/nav/breadcrumbs/breadcrumbs.test.tsx
new file mode 100644
index 0000000..40bb1b8
--- /dev/null
+++ b/src/components/organisms/nav/breadcrumbs/breadcrumbs.test.tsx
@@ -0,0 +1,22 @@
+import { describe, expect, it } from '@jest/globals';
+import { render, screen as rtlScreen } from '@testing-library/react';
+import { Breadcrumbs, type BreadcrumbsItem } from './breadcrumbs';
+
+const items: BreadcrumbsItem[] = [
+ { id: 'home', url: '#', name: 'Home' },
+ { id: 'blog', url: '#', name: 'Blog' },
+ { id: 'post1', url: '#', name: 'A Post' },
+];
+
+describe('Breadcrumbs', () => {
+ it('renders a list of items wrapped in a nav element', () => {
+ const ariaLabel = 'error tempore iure';
+
+ render(<Breadcrumbs aria-label={ariaLabel} items={items} />);
+
+ expect(rtlScreen.getByRole('navigation')).toHaveAccessibleName(ariaLabel);
+ expect(rtlScreen.getAllByRole('listitem')).toHaveLength(items.length);
+ // The last item should not be linked
+ expect(rtlScreen.getAllByRole('link')).toHaveLength(items.length - 1);
+ });
+});
diff --git a/src/components/organisms/nav/breadcrumbs/breadcrumbs.tsx b/src/components/organisms/nav/breadcrumbs/breadcrumbs.tsx
new file mode 100644
index 0000000..b6d3843
--- /dev/null
+++ b/src/components/organisms/nav/breadcrumbs/breadcrumbs.tsx
@@ -0,0 +1,66 @@
+import { type ForwardRefRenderFunction, forwardRef } from 'react';
+import { Nav, VisuallyHidden, type NavProps } from '../../../atoms';
+import { NavItem, NavLink, NavList } from '../../../molecules';
+import styles from './breadcrumbs.module.scss';
+
+export type BreadcrumbsItem = {
+ /**
+ * The item id.
+ */
+ id: string;
+ /**
+ * The item URL.
+ */
+ url: string;
+ /**
+ * The item name.
+ */
+ name: string;
+};
+
+export type BreadcrumbsProps = Omit<NavProps, 'children'> & {
+ /**
+ * The breadcrumbs items.
+ */
+ items: BreadcrumbsItem[];
+};
+
+const BreadcrumbsWithRef: ForwardRefRenderFunction<
+ HTMLElement,
+ BreadcrumbsProps
+> = ({ className = '', items, ...props }, ref) => {
+ const wrapperClass = `${styles.wrapper} ${className}`;
+ const sep = '>';
+
+ return (
+ <Nav {...props} className={wrapperClass} ref={ref}>
+ <NavList
+ isInline
+ isOrdered
+ // eslint-disable-next-line react/jsx-no-literals
+ spacing="xs"
+ >
+ {items.map((item, index) => {
+ const isLastItem = items.length === index + 1;
+
+ return (
+ <NavItem key={item.id}>
+ {isLastItem ? (
+ <VisuallyHidden>{item.name}</VisuallyHidden>
+ ) : (
+ <>
+ <NavLink href={item.url} label={item.name} />
+ <span aria-hidden className={styles.sep}>
+ {sep}
+ </span>
+ </>
+ )}
+ </NavItem>
+ );
+ })}
+ </NavList>
+ </Nav>
+ );
+};
+
+export const Breadcrumbs = forwardRef(BreadcrumbsWithRef);
diff --git a/src/components/organisms/nav/breadcrumbs/index.ts b/src/components/organisms/nav/breadcrumbs/index.ts
new file mode 100644
index 0000000..8d59853
--- /dev/null
+++ b/src/components/organisms/nav/breadcrumbs/index.ts
@@ -0,0 +1 @@
+export * from './breadcrumbs';
diff --git a/src/components/organisms/nav/index.ts b/src/components/organisms/nav/index.ts
index cb72765..ad899e0 100644
--- a/src/components/organisms/nav/index.ts
+++ b/src/components/organisms/nav/index.ts
@@ -1 +1,2 @@
+export * from './breadcrumbs';
export * from './pagination';
diff --git a/src/components/templates/page/page-layout.module.scss b/src/components/templates/page/page-layout.module.scss
index 09bb957..4615f60 100644
--- a/src/components/templates/page/page-layout.module.scss
+++ b/src/components/templates/page/page-layout.module.scss
@@ -6,13 +6,11 @@
@extend %grid;
grid-column: 1 / -1;
+ width: 100%;
padding: var(--spacing-md) 0;
> * {
grid-column: 2;
- }
-
- &__items {
font-size: var(--font-size-sm);
}
}
diff --git a/src/components/templates/page/page-layout.tsx b/src/components/templates/page/page-layout.tsx
index dbac43e..3fd5b02 100644
--- a/src/components/templates/page/page-layout.tsx
+++ b/src/components/templates/page/page-layout.tsx
@@ -14,8 +14,6 @@ import type { Approved, SendCommentInput, SingleComment } from '../../../types';
import { useIsMounted } from '../../../utils/hooks';
import { Heading, Notice, type NoticeKind, Sidebar } from '../../atoms';
import {
- Breadcrumb,
- type BreadcrumbItem,
PageFooter,
type PageFooterProps,
PageHeader,
@@ -27,6 +25,8 @@ import {
CommentsList,
type CommentsListProps,
TableOfContents,
+ Breadcrumbs,
+ type BreadcrumbsItem,
} from '../../organisms';
import styles from './page-layout.module.scss';
@@ -62,7 +62,7 @@ export type PageLayoutProps = {
/**
* The breadcrumb items.
*/
- breadcrumb: BreadcrumbItem[];
+ breadcrumb: BreadcrumbsItem[];
/**
* The breadcrumb JSON schema.
*/
@@ -127,6 +127,11 @@ export const PageLayout: FC<PageLayoutProps> = ({
withToC = false,
}) => {
const intl = useIntl();
+ const breadcrumbsLabel = intl.formatMessage({
+ defaultMessage: 'Breadcrumb',
+ description: 'PageLayout: an accessible name for the breadcrumb nav.',
+ id: 'm6a3BD',
+ });
const commentsTitle = intl.formatMessage({
defaultMessage: 'Comments',
description: 'PageLayout: comments title',
@@ -211,9 +216,9 @@ export const PageLayout: FC<PageLayoutProps> = ({
id="schema-breadcrumb"
type="application/ld+json"
/>
- <Breadcrumb
+ <Breadcrumbs
+ aria-label={breadcrumbsLabel}
className={styles.breadcrumb}
- itemClassName={styles.breadcrumb__items}
items={breadcrumb}
/>
<PageHeader
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 8581273..2fd2edf 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -35,10 +35,6 @@
"defaultMessage": "Tracking:",
"description": "AckeeToggle: select label"
},
- "16zl9Z": {
- "defaultMessage": "You are here:",
- "description": "Breadcrumb: You are here prefix"
- },
"18h/t0": {
"defaultMessage": "Discover {websiteName}'s writings. He talks about web development, Linux and open source mostly.",
"description": "BlogPage: SEO - Meta description"
@@ -63,10 +59,6 @@
"defaultMessage": "Projects",
"description": "Breadcrumb: projects label"
},
- "28nnDY": {
- "defaultMessage": "Breadcrumb",
- "description": "Breadcrumb: an accessible name for the breadcrumb nav."
- },
"2D9tB5": {
"defaultMessage": "Topics",
"description": "BlogPage: topics list widget title"
@@ -599,6 +591,10 @@
"defaultMessage": "Use Ctrl+c to copy",
"description": "usePrism: copy button error text"
},
+ "m6a3BD": {
+ "defaultMessage": "Breadcrumb",
+ "description": "PageLayout: an accessible name for the breadcrumb nav."
+ },
"nGss/j": {
"defaultMessage": "Ackee tracking (analytics)",
"description": "AckeeToggle: tooltip title"
diff --git a/src/i18n/fr.json b/src/i18n/fr.json
index 5687cdc..bebfc47 100644
--- a/src/i18n/fr.json
+++ b/src/i18n/fr.json
@@ -35,10 +35,6 @@
"defaultMessage": "Suivi :",
"description": "AckeeToggle: select label"
},
- "16zl9Z": {
- "defaultMessage": "Vous êtes ici :",
- "description": "Breadcrumb: You are here prefix"
- },
"18h/t0": {
"defaultMessage": "Découvrez les articles d’{websiteName}. Il écrit à propos de développement web, de Linux et du libre essentiellement.",
"description": "BlogPage: SEO - Meta description"
@@ -63,10 +59,6 @@
"defaultMessage": "Projets",
"description": "Breadcrumb: projects label"
},
- "28nnDY": {
- "defaultMessage": "Fil d’Ariane",
- "description": "Breadcrumb: an accessible name for the breadcrumb nav."
- },
"2D9tB5": {
"defaultMessage": "Sujets",
"description": "BlogPage: topics list widget title"
@@ -599,6 +591,10 @@
"defaultMessage": "Utilisez Ctrl+c pour copier",
"description": "usePrism: copy button error text"
},
+ "m6a3BD": {
+ "defaultMessage": "Fil d’Ariane",
+ "description": "PageLayout: an accessible name for the breadcrumb nav."
+ },
"nGss/j": {
"defaultMessage": "Suivi Ackee (analytique)",
"description": "AckeeToggle: tooltip title"
diff --git a/src/utils/hooks/use-breadcrumb.ts b/src/utils/hooks/use-breadcrumb.ts
index 5839299..57c27bd 100644
--- a/src/utils/hooks/use-breadcrumb.ts
+++ b/src/utils/hooks/use-breadcrumb.ts
@@ -1,11 +1,33 @@
/* eslint-disable max-statements */
import { useIntl } from 'react-intl';
import type { BreadcrumbList } from 'schema-dts';
-import type { BreadcrumbItem } from '../../components';
+import type { BreadcrumbsItem } from '../../components';
import { ROUTES } from '../constants';
import { slugify } from '../helpers';
import { useSettings } from './use-settings';
+const isArticle = (url: string) => url.startsWith(`${ROUTES.ARTICLE}/`);
+
+const isHome = (url: string) => url === '/';
+
+const isPageNumber = (url: string) => url.includes('/page/');
+
+const isProject = (url: string) => url.startsWith(`${ROUTES.PROJECTS}/`);
+
+const isSearch = (url: string) => url.startsWith(ROUTES.SEARCH);
+
+const isThematic = (url: string) =>
+ url.startsWith(`${ROUTES.THEMATICS.INDEX}/`);
+
+const isTopic = (url: string) => url.startsWith(`${ROUTES.TOPICS}/`);
+
+const hasBlogAsParent = (url: string) =>
+ isArticle(url) ||
+ isPageNumber(url) ||
+ isSearch(url) ||
+ isThematic(url) ||
+ isTopic(url);
+
export type useBreadcrumbProps = {
/**
* The current page title.
@@ -21,7 +43,7 @@ export type useBreadcrumbReturn = {
/**
* The breadcrumb items.
*/
- items: BreadcrumbItem[];
+ items: BreadcrumbsItem[];
/**
* The breadcrumb JSON schema.
*/
@@ -40,57 +62,54 @@ export const useBreadcrumb = ({
}: useBreadcrumbProps): useBreadcrumbReturn => {
const intl = useIntl();
const { website } = useSettings();
- const isArticle = url.startsWith(`${ROUTES.ARTICLE}/`);
- const isHome = url === '/';
- const isPageNumber = url.includes('/page/');
- const isProject = url.startsWith(`${ROUTES.PROJECTS}/`);
- const isSearch = url.startsWith(ROUTES.SEARCH);
- const isThematic = url.startsWith(`${ROUTES.THEMATICS.INDEX}/`);
- const isTopic = url.startsWith(`${ROUTES.TOPICS}/`);
-
- const homeLabel = intl.formatMessage({
- defaultMessage: 'Home',
- description: 'Breadcrumb: home label',
- id: 'j5k9Fe',
- });
- const items: BreadcrumbItem[] = [{ id: 'home', name: homeLabel, url: '/' }];
+ const labels = {
+ home: intl.formatMessage({
+ defaultMessage: 'Home',
+ description: 'Breadcrumb: home label',
+ id: 'j5k9Fe',
+ }),
+ blog: intl.formatMessage({
+ defaultMessage: 'Blog',
+ description: 'Breadcrumb: blog label',
+ id: 'Es52wh',
+ }),
+ projects: intl.formatMessage({
+ defaultMessage: 'Projects',
+ description: 'Breadcrumb: projects label',
+ id: '28GZdv',
+ }),
+ };
+
+ const items: BreadcrumbsItem[] = [
+ { id: 'home', name: labels.home, url: '/' },
+ ];
const schema: BreadcrumbList['itemListElement'][] = [
{
'@type': 'ListItem',
position: 1,
- name: homeLabel,
+ name: labels.home,
item: website.url,
},
];
- if (isHome) return { items, schema };
+ if (isHome(url)) return { items, schema };
- if (isArticle || isPageNumber || isSearch || isThematic || isTopic) {
- const blogLabel = intl.formatMessage({
- defaultMessage: 'Blog',
- description: 'Breadcrumb: blog label',
- id: 'Es52wh',
- });
- items.push({ id: 'blog', name: blogLabel, url: ROUTES.BLOG });
+ if (hasBlogAsParent(url)) {
+ items.push({ id: 'blog', name: labels.blog, url: ROUTES.BLOG });
schema.push({
'@type': 'ListItem',
position: 2,
- name: blogLabel,
+ name: labels.blog,
item: `${website.url}${ROUTES.BLOG}`,
});
}
- if (isProject) {
- const projectsLabel = intl.formatMessage({
- defaultMessage: 'Projects',
- description: 'Breadcrumb: projects label',
- id: '28GZdv',
- });
- items.push({ id: 'projects', name: projectsLabel, url: ROUTES.PROJECTS });
+ if (isProject(url)) {
+ items.push({ id: 'projects', name: labels.projects, url: ROUTES.PROJECTS });
schema.push({
'@type': 'ListItem',
position: 2,
- name: projectsLabel,
+ name: labels.projects,
item: `${website.url}${ROUTES.PROJECTS}`,
});
}