Setting up abandoned category view trigger in 1C-Bitrix
Category view is a weak signal of intent, but in a series of such views without transition to a product it's already a pattern of indecision. A user viewed "Laptops" three times, didn't open specific products and left. The abandoned category view trigger allows you to react to this pattern and push toward selection through personalized communication.
Problem: category views are not written to standard tables
Unlike products, the history of catalog section views in Bitrix is not tracked out of the box. The b_catalog_viewed_product table stores only products. Catalog categories are b_iblock_section, and there's no equivalent of CCatalogViewedProduct for sections.
This means you need to track section view yourself. Entry point — the bitrix:catalog.section or bitrix:catalog.section.list component. In the component template or via result_modifier.php add an AJAX request to your endpoint when the page loads.
Storing category view history
Create your own table via Bitrix ORM:
// Table class via D7
class ViewedSectionTable extends \Bitrix\Main\ORM\Data\DataManager
{
public static function getTableName(): string
{
return 'bl_catalog_viewed_section';
}
public static function getMap(): array
{
return [
new \Bitrix\Main\ORM\Fields\IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
new \Bitrix\Main\ORM\Fields\IntegerField('FUSER_ID', ['required' => true]),
new \Bitrix\Main\ORM\Fields\IntegerField('SECTION_ID', ['required' => true]),
new \Bitrix\Main\ORM\Fields\StringField('SITE_ID', ['size' => 2]),
new \Bitrix\Main\ORM\Fields\DatetimeField('DATE_VISIT'),
];
}
}
On each hit to section page — ViewedSectionTable::add() with FUSER_ID from CSaleUser::GetAnonymousUserID() or real USER_ID when authorized.
Determining category "abandonment"
Logic is more complex than for a product. Possible criteria options:
-
Simple: user viewed section X but didn't transition to any product from it (no entry in
b_catalog_viewed_productwith product from this section in same period) - Behavioral: user 2+ times in 24 hours opened same section without purchase — sign of indecision, needs help choosing
-- Users who viewed same section twice in 24 hours without purchase
SELECT fuser_id, section_id, COUNT(*) as visits
FROM bl_catalog_viewed_section
WHERE date_visit > NOW() - INTERVAL '24 hours'
GROUP BY fuser_id, section_id
HAVING COUNT(*) >= 2;
Personalizing trigger content
For category trigger it makes sense not just to remind "you viewed section" but to show top-3 products from this category. The selection is built via CIBlockElement::GetList() with SECTION_ID filter and sorted by CATALOG_QUANTITY or by number of orders from b_sale_order_basket.
If the system has a recommendation system configured (module ml or third-party service), you can request personalized recommendations by FUSER_ID for specific SECTION_ID.
Agent and deduplication
Similar to product trigger: agent in b_agent with 20–30 minute interval. Deduplication table bl_abandoned_section_sent with unique key on (fuser_id, section_id, DATE(sent_at)) — no more than one trigger per 24 hours for one pair.
Important nuance for hierarchical catalogs: if user viewed a subsection "Gaming Laptops" (child of "Laptops"), the trigger shouldn't fire twice — on child and parent section. Solution: when searching for duplicates, walk up the section tree via b_iblock_section.IBLOCK_SECTION_ID and check whether there was already a send on the parent section.
What we configure
- Creating
bl_catalog_viewed_sectiontable via ORM migration - AJAX call to log view from
bitrix:catalog.sectioncomponent template - Agent with logic for detecting abandoned views
- Query for top products of category for substitution in communication
- Deduplication table accounting for section hierarchy
- Mechanism excluding users who already bought product from this category







