Frequently Bought Together React component
A bundle builder for product pages: the current product plus add-ons joined by plus signs, each toggled with a check, greyed out when skipped, with bundle discount tiers, a counting total, savings and an Add all to cart button that confirms the items added.
About the Frequently Bought Together component
Frequently Bought Together turns the products people already buy together into a one-click bundle. The current product leads the row and the add-ons follow, each with a check that shoppers can turn off.
Bundle discount tiers reward adding more, and the total counts up or down as items are toggled, so the saving is easy to see. One button adds everything chosen to the cart and confirms how many items went in.
When to use it
Place it on product pages below the buy box, using pairings from your order data such as accessories, refills or items from the same collection.
Avoid it when the add-ons are unrelated or much more expensive than the main product; a bundle that feels random lowers trust in the recommendations.
Installation
Add the Frequently Bought Together component to your project with the shadcn CLI. It lands in components/frequently-bought-together.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add @reactframe/frequently-bought-togetherOr copy the source by hand and install its dependencies:
npm install motion clsx tailwind-mergeCollections
Use-case pages that compare Frequently Bought Together with the other components that do a similar job.
npm dependencies
Installed for you by the shadcn CLI.
Frequently Bought Together FAQ
- How is the bundle discount calculated?
- The highest tier whose count is reached applies its percentage to the subtotal of the chosen items, rounded to the cent. Change tiers or pass an empty array to turn bundle discounts off.
- Can shoppers remove the main product?
- No. The first item is the product on the page, so it is always included and shows a This item badge. Only the add-ons can be toggled.
- Why does the total count instead of jumping?
- A short count makes the change in price noticeable when items are toggled. It writes straight to the DOM instead of re-rendering, and with reduced motion it updates instantly.
- What does onAdd receive?
- The chosen items (main product first) and the discounted total. If it returns a promise, the button keeps its Adding state until the promise resolves.
- Is it accessible?
- Add-on cards are checkboxes with the name and price as the label and work with Space and Enter, the plus connectors are hidden from screen readers, the active tier is marked with aria-current and the hint and button text announce the changes.