Setting up automatic generation of SEO tags 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

SEO Tag Auto-Generation Setup for Bitrix CMS

SEO tag auto-generation — filling <title>, <meta name="description"> and <h1> according to rules based on element or section data. Needed when catalog contains thousands of items: manual filling isn't practical, and empty meta tags harm indexing.

Standard Templates in SEO Module

Basic tool — meta tag rules in Marketing → Search Engine Optimization → Meta Tags. For infoblock, set template with substitutions #NAME#, #SECTION_NAME#, #PROPERTY_{CODE}#. Covers most cases without programming.

For online store, typical template set:

Object Title Description
Catalog Element #NAME# — price, specifications Buy #NAME#. #PROPERTY_SHORT_DESC# Delivery from 1 day.
Catalog Section #NAME# — product catalog Wide selection in #NAME# section. #PROPERTY_SECTION_DESC#
Article Detail #NAME# | Blog #PREVIEW_TEXT#

Custom Generation via Events

When templates aren't enough (complex logic needed: different templates by property, adding related element data), use OnPageStart or OnBeforeProlog event handler in init.php:

AddEventHandler('main', 'OnBeforeProlog', function() {
    global $APPLICATION;

    // Only for catalog detail pages
    if (!preg_match('#^/catalog/([^/]+)/([^/]+)/#', $_SERVER['REQUEST_URI'])) {
        return;
    }

    // Can't get current element from component directly,
    // so use URL data or request separately
    $elementId = (int)$_REQUEST['ELEMENT_ID'];
    if (!$elementId) return;

    $el = \CIBlockElement::GetByID($elementId)->GetNext();
    if (!$el) return;

    $brand  = $el['PROPERTIES']['BRAND']['VALUE'] ?? '';
    $model  = $el['NAME'];
    $price  = \CCatalogProduct::GetByID($elementId)['PRICE'] ?? '';

    $APPLICATION->SetPageProperty('title',
        "{$brand} {$model} — buy for {$price} $ | Online Store"
    );
    $APPLICATION->SetPageProperty('description',
        "Buy {$brand} {$model} for {$price} $ with delivery across country. " .
        ($el['PROPERTIES']['SHORT_DESC']['VALUE'] ?? '')
    );
});

SetPageProperty call in OnBeforeProlog executes before page components, so the value reaches <head>.

Generating H1 Independently from Title

<title> and <h1> should differ — good practice. <h1> set via page property h1:

$APPLICATION->SetPageProperty('h1', $el['NAME']);

In page template:

<h1><?= $APPLICATION->GetPageProperty('h1') ?: $APPLICATION->GetTitle() ?></h1>

Mass Update of SEO Fields for Existing Elements

If need to fill SEO fields for thousands of existing products by template — done via script:

$res = \CIBlockElement::GetList(
    [],
    ['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'ACTIVE' => 'Y'],
    false,
    false,
    ['ID', 'NAME', 'IBLOCK_ID']
);

while ($el = $res->GetNextElement()) {
    $fields = $el->GetFields();
    $props  = $el->GetProperties();

    $seoTitle = $fields['NAME'] . ' — buy in online store';
    $seoDesc  = 'Buy ' . $fields['NAME'] . ' with delivery. ' .
                ($props['SHORT_DESC']['VALUE'] ?? '');

    \CIBlockElement::SetPropertyValuesEx($fields['ID'], $fields['IBLOCK_ID'], [
        'SEO_TITLE'       => $seoTitle,
        'SEO_DESCRIPTION' => $seoDesc,
    ]);
}

Script runs once. After execution, elements get filled SEO fields that override module template.

Implementation Timeline

Setting up auto-generation templates via SEO module — 1–2 hours. Custom generation with event logic + mass update of existing elements — 4–6 hours.