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=ascand/catalog/ - Smart filter page without SEF:
/catalog/?arrFilter_P1=100&set_filter=Y - HTTP and HTTPS versions
- With
wwwand 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.







