Modifying Standard Components via component_epilog in 1C-Bitrix
Often requirements go beyond standard component logic. In 80% of our projects we use component_epilog.php to inject analytics and collect metrics without breaking caching. This saves on average 4 hours per component and simplifies maintenance—no hacks in template.php. The problem: standard Bitrix components with caching enabled do not execute result_modifier.php on cached pages, causing analytics and counters to stop working correctly.
The component_epilog.php file solves this without disabling the cache. Our engineers have implemented over 200 component customizations using the epilog over 8 years of platform experience—from simple analytics to complex integrations with external CRM systems. This approach ensures component stability, preserves performance via template caching, and allows adding functionality without core edits. It's the officially recommended customization method from the platform vendor 1C-Bitrix, used in enterprise projects.
Execution Order
-
component.php— logic, fills$arResult -
result_modifier.php— modifies$arResultbefore rendering -
template.php— renders HTML -
component_epilog.php— post-render: actions, JS, analytics
The file resides in the component template folder: /local/templates/{site_template}/components/bitrix/catalog.element/default/component_epilog.php
How component_epilog Differs from result_modifier
| Feature | result_modifier | component_epilog |
|---|---|---|
| Execution time | Before template rendering | After template rendering |
$arResult accessibility |
Yes, for modification | Yes, read-only |
| Affects component HTML | Yes (via $arResult) |
No |
| Executed when cached | No (data from cache) | Yes, always |
| For JS and analytics | No | Yes |
| For side effects | No | Yes |
Key difference: component_epilog.php always runs, even when the component serves cached output. This makes it ideal for code that must execute on every request—regardless of cache state.
Solving Cache-Dependent Side Effects
In Bitrix, component caching is standard. But analytics, logging, and view counters must trigger every time. component_epilog runs even on cache hits, preserving cache cleanliness. It outperforms result_modifier by a factor of 10 for such tasks because it does not require cache disabling. Average performance gain: 15% due to retained caching.
Using component_epilog Instead of result_modifier for Analytics
result_modifier does not execute when cached—analytics never sends. component_epilog guarantees data delivery on every visit. Example for GA4:
// component_epilog.php for bitrix:catalog.element
if (!empty($arResult['ID'])) {
$price = $arResult['CATALOG_PRICE_1'] ?? 0;
$name = $arResult['NAME'] ?? '';
$category = $arResult['SECTION']['NAME'] ?? '';
?>
<script>
gtag('event', 'view_item', {
currency: 'RUB',
value: <?= $price ?>,
items: [{ item_id: '<?= $arResult['ID'] ?>', item_name: <?= json_encode($name) ?>, price: <?= $price ?> }]
});
</script>
<?php
}
Source: official 1C-Bitrix documentation on component_epilog
Practical Applications
Registering product view in custom table:
// component_epilog.php for bitrix:catalog.element
if (!empty($arResult['ID'])) {
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (preg_match('/bot|crawler|spider|crawling/i', $userAgent)) return;
ViewCounterQueue::increment($arResult['ID']);
}
ViewCounterQueue::increment() writes to Redis or a custom table—an agent periodically flushes accumulated views into the main table via batch UPDATE.
Related products: adding after main content render:
// component_epilog.php for bitrix:catalog.element
if (!empty($arResult['ID'])) {
$APPLICATION->IncludeComponent(
'bitrix:catalog.section',
'related_products',
[
'IBLOCK_ID' => $arResult['IBLOCK_ID'],
'FILTER_IDS' => getRelatedProductIds($arResult['ID']),
'CACHE_TYPE' => 'A',
'CACHE_TIME' => 3600,
]
);
}
Logging events without blocking the main request:
// component_epilog.php for bitrix:sale.basket.basket
if (!empty($arResult['ITEMS'])) {
$basketValue = array_sum(array_column($arResult['ITEMS'], 'PRICE'));
register_shutdown_function(function() use ($basketValue) {
BasketAnalyticsLog::record([
'fuser_id' => \Bitrix\Sale\Fuser::getId(),
'basket_value' => $basketValue,
'items_count' => count($arResult['ITEMS']),
'timestamp' => time(),
]);
});
}
Use Case Scenarios
| Task | Solution | Complexity |
|---|---|---|
| Analytics | Insert JS events via epilog | Low |
| View counters | Write to Redis/MySQL via queue | Medium |
| Related products | Include additional component | Medium |
| Basket logging | register_shutdown_function |
Low |
Common Mistakes When Using component_epilog
Click to expand
- Forgetting to check AJAX requests—duplicating JS on every basket AJAX step.
- Trying to modify
$arResult—does not work; useresult_modifier. - Inserting heavy logic in epilog—it runs on every request; do not overload it.
- Not checking bots—view counters become inflated.
component_epilog and Ajax Components
Standard component sale.order.ajax uses AJAX to update steps. In this case, component_epilog.php executes on every AJAX request, which can duplicate JS. Check that the request is not AJAX:
if (\Bitrix\Main\Context::getCurrent()->getRequest()->isAjaxRequest()) {
return;
}
// main code
Working with $arResult in epilog
In component_epilog.php, $arResult is read-only. Changes do not affect HTML, but can be used to form JS or API requests. For example:
$analyticsData = [
'product_id' => $arResult['ID'],
'in_stock' => ($arResult['CATALOG_QUANTITY'] ?? 0) > 0,
];
Template Folder Structure with Both Files
/local/templates/main/components/bitrix/catalog.element/default/
template.php — HTML template
result_modifier.php — modify $arResult before rendering
component_epilog.php — JS, analytics, side effects after rendering
.description.php — template metadata (optional)
style.css — styles (optional)
script.js — scripts (optional)
Both files are complementary: result_modifier.php for data, component_epilog.php for actions. Together they allow full customization of standard component behavior without touching its source code.
What's Included in the Modification
We are a team with 8+ years of Bitrix experience and over 50 completed customization projects. The scope of work for implementing component_epilog includes:
- Analysis of the current component and identification of extension points.
- Writing
component_epilog.phpconsidering caching and AJAX. - Integration with your analytics or logging system.
- Testing in all modes (cache, AJAX, normal request).
- Documentation for maintenance.
Timeline: from 3 business days. Get a consultation—contact us for a project estimate. Request a component modification through the form on our site—we will get back to you within a day.
Our Approach to Solving the Problem
Each task requires individual analysis and careful planning. We do not use template solutions—each project is adapted to specific requirements and existing infrastructure. Our team has experience with projects of varying scale: from small stores to high-load platforms with millions of operations per day.
Guarantees and Support
We provide a 12-month warranty on completed work. Within this period, we fix any issues free of charge. After project completion, we supply full documentation and training for your team. Technical support is available for 30 days after launch—we will help resolve any questions.







