Bulk SEO Tag Generation Configuration in 1C-Bitrix
A new catalog section — 3,000 products, each requiring a unique <title>, <meta name="description">, and OG tags. Writing them manually is not feasible. Bitrix supports template-based generation of SEO fields via its built-in SEO filter mechanism, and its capabilities are broad enough for most use cases.
Where SEO Fields Are Stored
SEO data for iblock elements is stored in the b_iblock_element_iprop table (iprop — iblock property). The relationship runs through b_iblock_iprop_template — template rules for sections and elements.
For individual elements: Product card → SEO tab — fields ELEMENT_META_TITLE, ELEMENT_META_KEYWORDS, ELEMENT_META_DESCRIPTION, ELEMENT_PAGE_TITLE.
Template rules are set at the iblock or section level: Iblocks → [iblock] → SEO tab. The template uses variables such as {=this.Name}, {=this.DetailText}, {=this.Property.BRAND.Value}.
Configuring Templates via the Interface
For most catalogs, template rules without custom scripts are sufficient:
Title template: {=this.Name} buy online — {=this.Property.BRAND.Value}
Description template: {=this.Name} from {=catalog.MinPrice}. Fast delivery. {=this.PreviewText}
In Iblocks → [iblock] → SEO Rules you can define different templates for different catalog sections — this allows category-specific customization without writing code.
Variables available in the template:
| Variable | Returns |
|---|---|
{=this.Name} |
Element name |
{=this.PreviewText} |
Announcement text |
{=this.Property.CODE.Value} |
Property value |
{=catalog.MinPrice} |
Minimum price |
{=section.Name} |
Section name |
Programmatic Generation via iPropertyValues
If the template mechanism is insufficient — generate SEO tags via a script and save them through \Bitrix\Iblock\InheritedProperty\ElementValues:
use Bitrix\Iblock\InheritedProperty\ElementValues;
$iblockId = 10;
$elementsRes = \CIBlockElement::GetList(
[],
['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y'],
false,
false,
['ID', 'NAME', 'PREVIEW_TEXT', 'XML_ID']
);
while ($element = $elementsRes->Fetch()) {
// Get the required properties
$props = \CIBlockElement::GetProperty($iblockId, $element['ID'], [], ['CODE' => ['BRAND', 'COLOR', 'MATERIAL']])->Fetch();
$brand = $props['BRAND_VALUE'] ?? '';
$title = "{$element['NAME']} {$brand} buy with delivery";
$description = "Buy {$element['NAME']} from {$brand}. " . strip_tags($element['PREVIEW_TEXT']);
$description = mb_substr($description, 0, 155);
$ipropValues = new ElementValues($iblockId, $element['ID']);
$ipropValues->setValues([
'ELEMENT_META_TITLE' => $title,
'ELEMENT_META_DESCRIPTION' => $description,
'ELEMENT_PAGE_TITLE' => $element['NAME'] . ($brand ? " ({$brand})" : ''),
]);
}
ElementValues::setValues() saves data to b_iblock_element_iprop and automatically invalidates the cache.
Generation via AI / Templating Engine
For more complex descriptions, you can pass product data to a GPT-compatible API and write the result back. This is justified when the catalog contains technical products with 1C-sourced descriptions that are unreadable for search engines.
The principle is the same: retrieve element data → compose description → save via ElementValues::setValues(). Important: rate-limit API requests and cache already-processed elements so that re-running the script does not consume API quota.
Checking for Uniqueness
After generation, it is worth checking for exact duplicate titles:
SELECT ELEMENT_META_TITLE, COUNT(*) AS cnt
FROM b_iblock_element_iprop
WHERE IBLOCK_ID = 10
GROUP BY ELEMENT_META_TITLE
HAVING cnt > 1
ORDER BY cnt DESC
LIMIT 50;
Duplicate titles are a signal that the template is not specific enough. Add a uniquifying property to the template: SKU, color, size.
Estimated Timelines
| Task | Time |
|---|---|
| Configuring template rules (no code) | 2–4 hours |
| Generation script for catalog up to 5,000 products | 1 day |
| AI-assisted description generation, 1,000–5,000 products | 2–4 days |







