Wishlist in 1C-Bitrix: Custom Favorites or Delayed Products?

Wishlist in 1C-Bitrix: Custom Favorites or Delayed Products? Here's a typical scenario: an online store owner on Bitrix asks for a "save for later" feature, but it turns out the standard delayed items mechanism in the cart doesn't work—when trying to place an order, the favorites are cleared. Or

Our competencies:

Frequently Asked Questions

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1415
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    995
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    733
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    863
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    772
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    1134

Wishlist in 1C-Bitrix: Custom Favorites or Delayed Products?

Here's a typical scenario: an online store owner on Bitrix asks for a "save for later" feature, but it turns out the standard delayed items mechanism in the cart doesn't work—when trying to place an order, the favorites are cleared. Or users complain that after login the list disappears. We've encountered this dozens of times and developed two proven approaches. Our experience: over 10 years of 1C-Bitrix development, 60+ projects with wishlist, 12-month guarantee on each. On average, working with a custom table is 3 times faster for catalogs with 10,000 products.

Why Delayed Products in the Cart Are Not Always the Solution?

The built-in sale module allows marking a product with the DELAY = Y flag. Technically, this is just a record in the b_sale_basket table:

$basket = \Bitrix\Sale\Basket::loadItemsForFUser( \Bitrix\Sale\Fuser::getId() ); $item = $basket->createItem('catalog', $productId); $item->setFields([ 'QUANTITY' => 1, 'DELAY' => 'Y', 'NAME' => $productName, 'PRICE' => $price, 'CURRENCY' => 'RUB', ]); $basket->save(); 

The bitrix:sale.basket.basket component with the parameter SHOW_DELAY = Y displays these items. Downside: delayed items are part of the cart. When the cart is cleared (e.g., after checkout), all delayed items are lost. There is also no separation between "in cart" and "wishlist" at the interface level. A full wishlist requires a separate entity.

Case Study: From Delayed to Custom

We had a client with a 15,000-product catalog who initially used delayed items. Users complained that items disappeared after purchase. We migrated to a custom table. The load time for the favorites page dropped from 2.5 seconds to 0.8 seconds, and user complaints ceased. The project took 2 days.

How to Build a Full-Fledged Wishlist on a Custom Table?

For storage independent of session and synchronization across devices, we use a separate table. Example DDL:

CREATE TABLE user_favorite_products ( ID INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, USER_ID INT NOT NULL, PRODUCT_ID INT NOT NULL, DATE_ADD DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_user_product (USER_ID, PRODUCT_ID) ); 

An ORM class via \Bitrix\Main\ORM\Data\DataManager allows standard add, delete, getList methods. Add/delete via AJAX controller:

class Favorite extends \Bitrix\Main\Engine\Controller { public function addAction(int $productId): array { $result = FavoriteTable::add([ 'USER_ID' => \Bitrix\Main\Engine\CurrentUser::get()->getId(), 'PRODUCT_ID' => $productId, ]); return $result->isSuccess() ? ['status' => 'ok'] : ['error' => $result->getErrors()]; } } 

How to Synchronize Favorites for Unauthenticated Users?

Unauthenticated users don't need a database record. We store an array of product IDs in localStorage:

  1. On click "add to favorites" — add/remove ID from the array and update localStorage.
  2. On page load, check authentication: if guest, read from localStorage and display favorite icons.
  3. On login, send accumulated IDs to the server via AJAX, which inserts them into the table. This prevents data loss.
  4. After sync, clear localStorage to avoid duplicates.

Comparison of Approaches

Aspect Delayed Items (Cart) Custom Table
Storage b_sale_basket user_favorite_products
Tied to cart Yes No
Guest support Session only localStorage + sync
Implementation complexity ~2-4 hours 1-2 working days
UI flexibility Limited Full customization

A custom table gives full control: you can add fields (color, size), group lists, display favorites separately from cart. This is especially important for large catalogs with 10,000+ items. According to our measurements, a query to a custom table runs 3 times faster than a select from b_sale_basket with the DELAY=Y filter.

How to Integrate Wishlist with an Existing Catalog?

During integration, we adapt the catalog component template: add a "Favorites" button with state (active/inactive) and a counter. We use the OnBuildGlobalMenu event to add a section to the personal account. For caching, we use tagged cache with the favorite tag. A typical mistake is forgetting the unique index on USER_ID+PRODUCT_ID, leading to duplicate entries on repeated clicks. Also handle the case where a guest is already logged in on another tab—sync could lose data. Use localStorage for guests, not the session, otherwise the list won't survive a page reload.

What's Included in the Work

  • Technical specification with logic and interface description.
  • Development of the "Favorites" button component with states and counter.
  • Server controller for add/delete.
  • Guest storage (localStorage) and synchronization on login.
  • Integration into the existing catalog with template adaptation.
  • Documentation and instructions for content manager.
  • Access to the code repository.
  • 12-month code guarantee.

Stages of Work

Stage Duration Result
Analysis 2-4 hours Technical specification
Design 1-2 days Database architecture
Development 2-4 days Working prototype
Integration 1-2 days Embedding into catalog
Testing 1 day QA report
Documentation 4 hours Instruction

Cost and Timeline

Timelines depend on the chosen approach. Standard delayed items: from 2 to 4 hours. Custom wishlist with synchronization: from 1 to 2 working days. Complex integrations (e.g., synchronization with a mobile app) are discussed separately. Cost is calculated individually after analyzing your project. Get a consultation — we'll analyze your case for free. Order a turnkey wishlist implementation. This saves time on development from scratch and avoids typical mistakes.

For architecture study, we recommend Bitrix ORM documentation and Wikipedia on Web Storage API.