Skip to content

Added breadcrumbs on PDP - #107

Merged
damianlegawiec merged 1 commit into
mainfrom
feature/pdp-breadcrumbs
Apr 3, 2026
Merged

Added breadcrumbs on PDP#107
damianlegawiec merged 1 commit into
mainfrom
feature/pdp-breadcrumbs

Conversation

@damianlegawiec

@damianlegawiec damianlegawiec commented Apr 3, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features
    • Added breadcrumb navigation on product pages to display the category hierarchy and improve navigation context.
    • Enhanced search engine visibility with breadcrumb structured data on product pages.
    • Product pages now preserve category context when navigating from category listings.

@vercel

vercel Bot commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
storefront Ready Ready Preview, Comment Apr 3, 2026 10:54am

Request Review

@coderabbitai

coderabbitai Bot commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This change threads categoryId through the product display component hierarchy (ProductListingLayout → ProductGrid → ProductCard) and enhances breadcrumb functionality. The product page now accepts an optional category_id query parameter, derives the relevant category, renders breadcrumbs with category links and product name, and generates breadcrumb JSON-LD structured data.

Changes

Cohort / File(s) Summary
Product Page Breadcrumb Logic
src/app/[country]/[locale]/(storefront)/products/[slug]/page.tsx
Integrated searchParams to capture optional category_id, added findBreadcrumbCategory helper to match or default to first category, renders breadcrumb UI and breadcrumb JSON-LD when category is available.
Breadcrumb Component
src/components/navigation/Breadcrumbs.tsx
Extended props to accept optional productName; when provided, renders category as a clickable link followed by non-clickable product name; otherwise treats category as final non-clickable item.
Product Category Threading
src/components/products/ProductCard.tsx, src/components/products/ProductGrid.tsx, src/components/products/ProductListingLayout.tsx, src/app/[country]/[locale]/(storefront)/c/[...permalink]/CategoryProductsContent.tsx
Added optional categoryId prop across the component chain; ProductCard conditionally appends ?category_id query parameter to product links when categoryId is provided.
Data & SEO Configuration
src/lib/data/cached.ts
Added "categories.ancestors" to PRODUCT_PAGE_EXPAND to ensure ancestor category data is fetched.
Breadcrumb JSON-LD
src/lib/seo.ts
Extended buildBreadcrumbJsonLd to optionally accept product details and append a product breadcrumb item to the structured data output.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Use Categories #51: Modifies the same component chain (CategoryProductsContent, ProductListingLayout, ProductGrid, ProductCard) to thread category-related props and enhance category awareness throughout the product display flow.
  • Add SEO support: meta tags, OpenGraph, and JSON-LD #21: Extends breadcrumb JSON-LD generation and updates cached data expansion configuration, directly building upon the SEO and caching utilities modified in this PR.
  • Add mobile-responsive header with hamburger menu #77: Concurrently modifies ProductGrid.tsx responsive styling, affecting the same component where categoryId prop forwarding is introduced.

Poem

🐰 A category link, now clickable and bright,
Breadcrumbs guide travelers through storefront's light,
Thread by thread, props cascade down with care,
Product and ancestor, a structured pair,
JSON-LD whispers what categories share! 🌿

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Added breadcrumbs on PDP' accurately summarizes the main change in this pull request, which adds breadcrumb navigation to the Product Details Page.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/pdp-breadcrumbs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/components/products/ProductCard.tsx (1)

59-59: Encode category_id when building product links.

Direct interpolation can break URLs when values contain reserved characters. Build the query string with URLSearchParams for safe encoding.

🔧 Suggested fix
-      href={`${basePath}/products/${product.slug}${categoryId ? `?category_id=${categoryId}` : ""}`}
+      href={`${basePath}/products/${product.slug}${
+        categoryId
+          ? `?${new URLSearchParams({ category_id: categoryId }).toString()}`
+          : ""
+      }`}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/products/ProductCard.tsx` at line 59, The product link
currently interpolates categoryId directly into the href in ProductCard
(href={`${basePath}/products/${product.slug}${categoryId ?
`?category_id=${categoryId}` : ""}`), which can break for reserved/unsafe
characters; change the link construction to build the query string with
URLSearchParams (or new URLSearchParams().append('category_id', categoryId)) and
append the encoded params only when non-empty so basePath, product.slug, and
category_id are correctly encoded.
src/lib/data/cached.ts (1)

6-12: Split product expand fields for PDP vs metadata to avoid over-fetch.

PRODUCT_PAGE_EXPAND is shared by both PDP and metadata, but metadata generation does not consume categories.ancestors (see src/lib/metadata/product.ts:18+). This adds unnecessary payload and latency to metadata requests.

♻️ Suggested refactor
-export const PRODUCT_PAGE_EXPAND = [
+export const PRODUCT_SHARED_EXPAND = [
   "variants",
   "media",
   "option_types",
   "custom_fields",
+];
+
+export const PRODUCT_PAGE_EXPAND = [
+  ...PRODUCT_SHARED_EXPAND,
   "categories.ancestors",
 ];

Then switch metadata to PRODUCT_SHARED_EXPAND (or a dedicated metadata expand constant).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/data/cached.ts` around lines 6 - 12, PRODUCT_PAGE_EXPAND currently
includes "categories.ancestors" and is used both for PDP and metadata
generation, causing extra payload; split the expands into two constants (e.g.,
PRODUCT_SHARED_EXPAND containing
"variants","media","option_types","custom_fields" and PRODUCT_PAGE_EXPAND adding
"categories.ancestors"), then update the metadata code that currently
imports/uses PRODUCT_PAGE_EXPAND (see product metadata code referencing product
expands) to use PRODUCT_SHARED_EXPAND (or a dedicated metadata expand constant)
so metadata requests no longer fetch categories.ancestors.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/components/products/ProductCard.tsx`:
- Line 59: The product link currently interpolates categoryId directly into the
href in ProductCard (href={`${basePath}/products/${product.slug}${categoryId ?
`?category_id=${categoryId}` : ""}`), which can break for reserved/unsafe
characters; change the link construction to build the query string with
URLSearchParams (or new URLSearchParams().append('category_id', categoryId)) and
append the encoded params only when non-empty so basePath, product.slug, and
category_id are correctly encoded.

In `@src/lib/data/cached.ts`:
- Around line 6-12: PRODUCT_PAGE_EXPAND currently includes
"categories.ancestors" and is used both for PDP and metadata generation, causing
extra payload; split the expands into two constants (e.g., PRODUCT_SHARED_EXPAND
containing "variants","media","option_types","custom_fields" and
PRODUCT_PAGE_EXPAND adding "categories.ancestors"), then update the metadata
code that currently imports/uses PRODUCT_PAGE_EXPAND (see product metadata code
referencing product expands) to use PRODUCT_SHARED_EXPAND (or a dedicated
metadata expand constant) so metadata requests no longer fetch
categories.ancestors.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3c60d909-efc9-4636-903e-7480ea972215

📥 Commits

Reviewing files that changed from the base of the PR and between 05f095f and 4691612.

📒 Files selected for processing (8)
  • src/app/[country]/[locale]/(storefront)/c/[...permalink]/CategoryProductsContent.tsx
  • src/app/[country]/[locale]/(storefront)/products/[slug]/page.tsx
  • src/components/navigation/Breadcrumbs.tsx
  • src/components/products/ProductCard.tsx
  • src/components/products/ProductGrid.tsx
  • src/components/products/ProductListingLayout.tsx
  • src/lib/data/cached.ts
  • src/lib/seo.ts

@damianlegawiec
damianlegawiec merged commit 1add7d6 into main Apr 3, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant