Facebook Pixel Setup on 1C-Bitrix
Facebook pixel doesn't work "out of the box" on Bitrix — it's not about code complexity, but because standard script integration conflicts with caching and event models. Basic pixel code is inserted in header via header.php or site settings, but without event transmission it's just a visit counter, nothing more.
Where the Base Code Lives and Why There Are Problems
The site template in Bitrix stores header.php in /bitrix/templates/<template_name>/. Inserting script directly into file works but is inconvenient: template changes lose the code, and composite templates (bitrix:page.polymorph) cache some blocks and pixel may not fire on cached pages.
Better to use bitrix:main.include component with AREA_FILE_SHOW = head, or subscribe to the OnEpilog event in /bitrix/php_interface/init.php:
AddEventHandler("main", "OnEpilog", function() {
$pixelId = COption::GetOptionString("main", "fb_pixel_id", "");
if ($pixelId) {
echo '<script>/* FB Pixel code with id: ' . htmlspecialchars($pixelId) . ' */</script>';
}
});
Store pixel ID in b_option via COption::SetOptionString. Never hardcode in template — if moving to another domain you'll have to search every file.
Standard Events and Catalog Data Transmission
For e-commerce, three events matter: ViewContent, AddToCart, Purchase. All must send product parameters — content_ids, content_type, value, currency.
ViewContent — fires on product detail page. The bitrix:catalog.element component generates the page, product data is available in $arResult. Customize the component's template.php and add fbq('track', 'ViewContent', {...}) call with substituting $arResult["ID"] and $arResult["PRICES"].
AddToCart — trickier. Adding to cart in Bitrix goes via AJAX request to sale.basket.basket or directly via CSaleBasket::Add(). Pixel event should fire in JS callback after successful response. In Bitrix core, OnSaleBasketItemAdd event handles basket addition — you can use this for server-side transmission via Conversions API, but that's another story.
Purchase — fires on thank_you page or in bitrix:sale.order.ajax component after successful checkout. $arResult["ORDER_ID"] has the order ID, get amount from CSaleOrder::GetByID().
Conversions API as Pixel Supplement
Browser pixel loses data due to ad blockers and iOS restrictions. Facebook recommends duplicating events via server-side Conversions API. Request goes from your server to graph.facebook.com/v18.0/<pixel_id>/events with access token.
In Bitrix, implement via CURLFile or standard \Bitrix\Main\Web\HttpClient. Subscribe to OnSaleOrderSaved event and send Purchase with hashed email (sha256) and event_id for deduplication with browser event.
Bitrix bitrix.main module version 22+ includes \Bitrix\Main\Web\HttpClient — use it, not file_get_contents, to not depend on allow_url_fopen config.
Testing and Verification
After setup, check via Facebook Pixel Helper (Chrome extension) and via Events Manager in Facebook account — "Event Testing" tab. Test mode shows real payload breakdown with validation errors.
Typical issue: event fires twice — browser and server arrive without event_id. Without deduplication Facebook counts them as two conversions. event_id should match in JS call fbq('track', 'Purchase', data, {eventID: 'order_123'}) and server request.







