Skip to content

feat: Add out-of-stock/backorder message to product lists#2739

Merged
Tharaae merged 1 commit intocanaryfrom
BACK-375
Dec 10, 2025
Merged

feat: Add out-of-stock/backorder message to product lists#2739
Tharaae merged 1 commit intocanaryfrom
BACK-375

Conversation

@Tharaae
Copy link
Copy Markdown
Contributor

@Tharaae Tharaae commented Dec 2, 2025

What/Why?

Display the backorder message or out-of-stock messages on the product card in different product lists according to the product stock status and the store settings.

Testing

Screenshots
Home page featured products lists
Screenshot 2025-12-02 at 3 41 24 pm

Category PLP
Screenshot 2025-12-02 at 3 40 42 pm

Brand PLP
Screenshot 2025-12-02 at 3 40 00 pm

Searc
Screenshot 2025-12-02 at 3 39 10 pm
h PLP

Migration

While rebasing, there might be some conflicts if there is some custom styling of the product card component. Those conflicts may occur in the following files:

  • core/vibes/soul/primitives/product-card/index.tsx

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Dec 2, 2025

🦋 Changeset detected

Latest commit: 6c10aad

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@bigcommerce/catalyst-core Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented Dec 2, 2025

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

Project Deployment Preview Comments Updated (UTC)
catalyst-b2b Ready Ready Preview Comment Dec 10, 2025 4:31am
catalyst-canary Ready Ready Preview Comment Dec 10, 2025 4:31am
2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
catalyst Ignored Ignored Dec 10, 2025 4:31am
catalyst-uplift-vertex Ignored Ignored Dec 10, 2025 4:31am

Copy link
Copy Markdown
Contributor

@jorgemoya jorgemoya left a comment

Choose a reason for hiding this comment

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

Looking good, just have a couple of comments!

Comment thread core/app/[locale]/(default)/(faceted)/brand/[slug]/page-data.ts
Comment thread core/app/[locale]/(default)/(faceted)/brand/[slug]/page-data.ts
Comment thread core/app/[locale]/(default)/(faceted)/brand/[slug]/page.tsx Outdated
Comment thread core/data-transformers/product-card-transformer.ts
Comment thread core/data-transformers/product-card-transformer.ts
Comment thread core/data-transformers/product-card-transformer.ts Outdated
Comment thread core/data-transformers/product-card-transformer.ts
Comment on lines +32 to +40
const baseVariant = removeEdgesAndNodes(product.variants).at(0);

if (!baseVariant?.inventory?.byLocation) {
return undefined;
}

const inventoryByLocation = removeEdgesAndNodes(baseVariant.inventory.byLocation).at(0);

return inventoryByLocation?.backorderMessage || undefined;
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.

Can you add a comment of what this is doing? I'm not familiar why this !baseVariant?.inventory?.byLocation warrants no message.

Should we also default a backorderMessage that we define in the Catalyst dictionary instead of returning undefined?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's up to the merchant to decide whether to display a backorder message or not by allocating a backorder message to a product / product variant. So, it can be undefined.

Comment thread core/vibes/soul/primitives/product-card/index.tsx
Comment thread core/vibes/soul/primitives/product-card/index.tsx
Copy link
Copy Markdown
Contributor

@jorgemoya jorgemoya left a comment

Choose a reason for hiding this comment

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

The problem I'm seeing with this feature is using strings defined by the merchant in the CP that are not multi-lang or translatable (as far as we know). We've skipped using these fields in Catalyst so that the translated experience remains consistent. To me, a good workaround is to simply use the Catalyst dictionary instead of fetching from GQL.

Tagging our Catalyst PM to provide some input on this. @bc-erich

Comment thread core/components/product-variants-inventory/fragment.ts
Comment on lines +4 to +24
fragment ProductVariantsInventoryFragment on Product {
variants {
edges {
node {
entityId
sku
inventory {
byLocation {
edges {
node {
locationEntityId
backorderMessage
}
}
}
}
}
}
}
}
`);
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.

Seems to me you only use the base variant. Could you modify this fragment to only include the first (unless I'm missing something)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The same fragment will be used in product details page as well. So, I wanted to avoid duplicate code.

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.

This is a very taxing query that is multiplied by number of products in a given PLP page. For PDP it's not a big deal, but if you are showing 20-30 products in a given PLP, I believe this is simply too much.

There's two options:

  1. Duplicate the code
  2. Fragment can include a first prop (example PricingFragment)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'll go with option one

Comment thread core/data-transformers/product-card-transformer.ts
<span
className={clsx(
'block font-semibold',
'line-clamp-2 font-semibold',
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.

Can we include changes like these in a separate PR for review?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Why can't we get it reviewed in this PR? 🤔

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.

This is a complex PR that will be difficult for consumers of Catalyst to merge into their custom codebases. If this change is not related to the intent of this PR, it is much easier for consumers to see this change as a separate PR that is tracked with it's own migration and changeset release notes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This change to limit the product name to product name on the card to two line followed by "..." if longer, is requested by the Jess as per her agreement with @andrewreifman. It's related to this PR to control the card size/layout while adding more info to it which is the backorder message.

Comment thread core/vibes/soul/primitives/product-card/index.tsx
numberOfReviews
averageRating
}
variants {
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.

Still need to query only the first one, since it seems that is all you need.

Suggested change
variants {
variants(first: 1) {

Comment thread .changeset/tricky-plants-teach.md Outdated
- Add the backorder message if the product has no on-hand stock and is available for backorder and the store/product is set to display the backorder message

## Migration
For existing Catalyst stores, to get the newly added feature, simply rebase the existing code with the new release code. The files to be rebased for this change to be applied are:
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.

Can you leverage AI and see if it can give you a better migration path for merchants that don't rebase?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

AI did not do a good job extracting the detailed steps for migration. So, I explained it myself in more details.

Copy link
Copy Markdown
Contributor

@jorgemoya jorgemoya left a comment

Choose a reason for hiding this comment

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

LGTM!

@Tharaae Tharaae added this pull request to the merge queue Dec 10, 2025
Merged via the queue into canary with commit e155398 Dec 10, 2025
12 checks passed
@Tharaae Tharaae deleted the BACK-375 branch December 10, 2025 23:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants