aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils/hooks/use-breadcrumb.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/hooks/use-breadcrumb.ts')
-rw-r--r--src/utils/hooks/use-breadcrumb.ts107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/utils/hooks/use-breadcrumb.ts b/src/utils/hooks/use-breadcrumb.ts
new file mode 100644
index 0000000..5839299
--- /dev/null
+++ b/src/utils/hooks/use-breadcrumb.ts
@@ -0,0 +1,107 @@
+/* eslint-disable max-statements */
+import { useIntl } from 'react-intl';
+import type { BreadcrumbList } from 'schema-dts';
+import type { BreadcrumbItem } from '../../components';
+import { ROUTES } from '../constants';
+import { slugify } from '../helpers';
+import { useSettings } from './use-settings';
+
+export type useBreadcrumbProps = {
+ /**
+ * The current page title.
+ */
+ title: string;
+ /**
+ * The current page url.
+ */
+ url: string;
+};
+
+export type useBreadcrumbReturn = {
+ /**
+ * The breadcrumb items.
+ */
+ items: BreadcrumbItem[];
+ /**
+ * The breadcrumb JSON schema.
+ */
+ schema: BreadcrumbList['itemListElement'][];
+};
+
+/**
+ * Retrieve the breadcrumb items.
+ *
+ * @param {useBreadcrumbProps} props - An object (the current page title & url).
+ * @returns {useBreadcrumbReturn} The breadcrumb items and its JSON schema.
+ */
+export const useBreadcrumb = ({
+ title,
+ url,
+}: 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 schema: BreadcrumbList['itemListElement'][] = [
+ {
+ '@type': 'ListItem',
+ position: 1,
+ name: homeLabel,
+ item: website.url,
+ },
+ ];
+
+ if (isHome) 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 });
+ schema.push({
+ '@type': 'ListItem',
+ position: 2,
+ name: blogLabel,
+ 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 });
+ schema.push({
+ '@type': 'ListItem',
+ position: 2,
+ name: projectsLabel,
+ item: `${website.url}${ROUTES.PROJECTS}`,
+ });
+ }
+
+ items.push({ id: slugify(title), name: title, url });
+ schema.push({
+ '@type': 'ListItem',
+ position: schema.length + 1,
+ name: title,
+ item: `${website.url}${url}`,
+ });
+
+ return { items, schema };
+};