Setting up canonical URLs in 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • 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
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Canonical URL Setup for Bitrix CMS

Duplicate content — one of the frequent SEO problems in Bitrix. The same product is accessible via multiple URLs: through catalog sections, through search, with filter GET parameters, with session parameters. Without the <link rel="canonical"> tag, search engine decides which URL is primary — and not always correctly.

Where URL Duplicates Occur in Bitrix

  • Product accessible from multiple catalog sections (infoblock with multiple section binding)
  • Page with GET parameters: /catalog/?sort=price&order=asc and /catalog/
  • Smart filter page without SEF: /catalog/?arrFilter_P1=100&set_filter=Y
  • HTTP and HTTPS versions
  • With www and without

Canonical via Component

Standard Bitrix components (bitrix:catalog.element, bitrix:catalog.section) have no built-in canonical tag output. Must be added to component template.

In product detail template.php:

// Get canonical URL of element
$canonicalUrl = $APPLICATION->GetCurDir() . CIBlockElement::GetDetailPageUrl(
    $arResult['IBLOCK']['DETAIL_PAGE_URL'],
    $arResult
);

// Output in HEAD via AddHeadString
$APPLICATION->AddHeadString(
    '<link rel="canonical" href="https://site.ru' . htmlspecialchars($canonicalUrl) . '" />',
    true
);

Canonical for Filter Pages

Smart filter pages with non-empty parameters should have canonical to base section page or to filter SEF URL (if URL-friendly filter is used).

In smart filter or section component template:

$isFiltered = !empty($_REQUEST['set_filter']) || !empty($_REQUEST['arrFilter_P1']);
if ($isFiltered) {
    $canonicalUrl = $APPLICATION->GetCurPage(); // path only, no GET parameters
    $APPLICATION->AddHeadString('<link rel="canonical" href="https://site.ru' . $canonicalUrl . '" />');
}

Canonical for Pagination

Pages /catalog/?PAGEN_1=2 — debatable. Options:

  • Canonical to first page (aggressive, loses link weight)
  • Don't set canonical, use rel="prev" / rel="next" (outdated, Google doesn't consider)
  • Unique canonical for each pagination page (recommended with unique content per page)

Global Canonical Setup via init.php

For centralized canonical setup without changing each template:

// /local/php_interface/init.php
AddEventHandler('main', 'OnEndBufferContent', function(&$content) {
    global $APPLICATION;
    $canonical = 'https://site.ru' . $APPLICATION->GetCurPage();
    $tag = '<link rel="canonical" href="' . htmlspecialchars($canonical) . '" />';
    $content = str_replace('</head>', $tag . '</head>', $content);
});

Approach is crude — works for simple sites. For filter catalogs, exception logic needed.

Implementation Timeline

Setting up canonical for product cards and catalog sections — 2–4 hours. Full implementation with filter pages, pagination, custom URLs — 4–8 hours.