diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx
index ab75b6e7e..423a559f2 100644
--- a/app/product/[handle]/page.tsx
+++ b/app/product/[handle]/page.tsx
@@ -2,6 +2,7 @@ import type { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { Suspense } from 'react';
+import BreadcrumbComponent from 'components/breadcrumb';
import { GridTileImage } from 'components/grid/tile';
import Footer from 'components/layout/footer';
import { Gallery } from 'components/product/gallery';
@@ -82,7 +83,8 @@ export default async function ProductPage({ params }: { params: { handle: string
}}
/>
-
+
+
& {
+ separator?: React.ReactNode;
+ }
+>(({ ...props }, ref) => );
+Breadcrumb.displayName = 'Breadcrumb';
+
+const BreadcrumbList = forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ )
+);
+BreadcrumbList.displayName = 'BreadcrumbList';
+
+const BreadcrumbItem = forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ )
+);
+BreadcrumbItem.displayName = 'BreadcrumbItem';
+
+const BreadcrumbLink = ({
+ className,
+ children,
+ ...props
+}: LinkProps & { className?: string; children: ReactNode }) => {
+ return (
+
+ {children}
+
+ );
+};
+
+BreadcrumbLink.displayName = 'BreadcrumbLink';
+
+const BreadcrumbPage = forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ )
+);
+BreadcrumbPage.displayName = 'BreadcrumbPage';
+
+const BreadcrumbSeparator = ({ children, className, ...props }: React.ComponentProps<'li'>) => (
+ svg]:size-3.5', className)}
+ {...props}
+ >
+ {children ?? }
+
+);
+BreadcrumbSeparator.displayName = 'BreadcrumbSeparator';
+
+const BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<'span'>) => (
+
+
+ More
+
+);
+BreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis';
+
+export {
+ Breadcrumb,
+ BreadcrumbEllipsis,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbList,
+ BreadcrumbPage,
+ BreadcrumbSeparator
+};
diff --git a/components/breadcrumb/index.tsx b/components/breadcrumb/index.tsx
new file mode 100644
index 000000000..a5d532efd
--- /dev/null
+++ b/components/breadcrumb/index.tsx
@@ -0,0 +1,62 @@
+import { getProduct } from 'lib/shopify';
+import { Fragment } from 'react';
+import {
+ Breadcrumb,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbList,
+ BreadcrumbPage,
+ BreadcrumbSeparator
+} from './breadcrumb-list';
+
+type BreadcrumbProps = {
+ type: 'product' | 'collection';
+ handle: string;
+};
+
+const BreadcrumbComponent = async ({ type, handle }: BreadcrumbProps) => {
+ const items: Array<{ href: string; title: string }> = [{ href: '/', title: 'Home' }];
+
+ if (type === 'product') {
+ const product = await getProduct(handle);
+ if (!product) return null;
+ const collection = product?.collections.nodes.length ? product.collections.nodes[0] : null;
+
+ if (collection) {
+ items.push({
+ href: `/search/${collection.handle}`,
+ title: collection.title
+ });
+ }
+
+ items.push({
+ title: product.title,
+ href: `/product/${product.handle}`
+ });
+ }
+
+ return (
+
+
+ {items.slice(0, items.length).map((item, index) => (
+
+ {index === items.length - 1 ? (
+
+ {item.title}
+
+ ) : (
+ <>
+
+ {item.title}
+
+
+ >
+ )}
+
+ ))}
+
+
+ );
+};
+
+export default BreadcrumbComponent;
diff --git a/lib/shopify/fragments/product.ts b/lib/shopify/fragments/product.ts
index be14dedca..aa194ccbb 100644
--- a/lib/shopify/fragments/product.ts
+++ b/lib/shopify/fragments/product.ts
@@ -24,6 +24,12 @@ const productFragment = /* GraphQL */ `
currencyCode
}
}
+ collections(first: 1) {
+ nodes {
+ title
+ handle
+ }
+ }
variants(first: 250) {
edges {
node {
diff --git a/lib/shopify/types.ts b/lib/shopify/types.ts
index 3f80d4a3e..5069ee168 100644
--- a/lib/shopify/types.ts
+++ b/lib/shopify/types.ts
@@ -127,6 +127,12 @@ export type ShopifyProduct = {
seo: SEO;
tags: string[];
updatedAt: string;
+ collections: {
+ nodes: {
+ title: string;
+ handle: string;
+ }[];
+ };
};
export type ShopifyCartOperation = {