На практике cron заливает 500 товаров из 1С: в логе CIBlockElement::Update вернул true, NAME и цены на месте, а в браузере title пустой. Типичная проблема: разработчик ищет ELEMENT_META_TITLE в GetByID и пишет meta в PROPERTY_VALUES — записи не работает, эффекта нет. SEO в 1С-Битрикс живет в ключе IPROPERTY_TEMPLATES, а не в обычных полях элемента. Ниже — запись шаблонов через Update/Add, чтение ElementValues::getValues(), наследование от раздела, сброс кеша clearValues() и чек-лист, чтобы view-source совпал с API.
IPROPERTY_TEMPLATES - специальный ключ массива полей CIBlockElement::Add/Update в 1С-Битрикс: Управление сайтом для записи SEO-шаблонов элемента инфоблока (ELEMENT_META_TITLE, ELEMENT_META_DESCRIPTION, ELEMENT_META_KEYWORDS, ELEMENT_PAGE_TITLE, alt/title картинок). Вычисленное значение с учетом наследования от раздела и инфоблока читают через Bitrix\Iblock\InheritedProperty\ElementValues::getValues(), не через GetByID. Сегодня: откройте вкладку SEO в админке, перенесите шаблон в IPROPERTY_TEMPLATES при Update, проверьте getValues() и view-source.
Речь про 1С-Битрикс: Управление сайтом на вашем хостинге, не про Bitrix24 CRM. Элемент инфоблока - товар, новость, услуга в каталоге CMS. Создаете карточку с нуля - CIBlockElement::Add с IPROPERTY_TEMPLATES в том же массиве. Меняете поля без SEO - CIBlockElement::Update. Свойства элемента (цена, бренд) - отдельная тема: SetPropertyValues, не путайте с SEO-шаблонами.
Разберите, когда SEO-поля нужно писать через API
SEO-вкладка в админке работает для ручной правки. Программная запись meta title элемента инфоблока битрикс нужна при импорте из 1С, cron-обмене, миграции каталога и массовой генерации шаблонов. API (Application Programming Interface) здесь - PHP-скрипт, который дергает методы Битрикса без браузера.
| Ситуация | Админка SEO | IPROPERTY_TEMPLATES в API |
|---|---|---|
| Одна новость | Быстрее | Избыточно |
| Импорт 3000 SKU ночью | Нереально | Обязателен API |
| Обмен JSON с внешней PIM | Нет UI | Update + getValues() |
| Только NAME и цена | Шаблон раздела подставит title | Не трогайте IPROPERTY_TEMPLATES |
NAME и PREVIEW_TEXT - поля карточки; SEO meta - наследуемые шаблоны в b_iblock_iproperty с версии 14.0.0, не пользовательские свойства.
Делайте: API для массовых сценариев. Не делайте: писать ELEMENT_META_TITLE в PROPERTY_VALUES - это другой слой данных.
Что такое IPROPERTY_TEMPLATES и когда он нужен
IPROPERTY_TEMPLATES - ключ в $arFields при Add/Update: не готовый title, а шаблон "{=this.NAME} - Каталог". Битрикс вычисляет итог по цепочке инфоблок → раздел → элемент.
Нужен, когда скрипт задает SEO-шаблон. Не нужен, если хватает наследования от раздела.
Запишите SEO через CIBlockElement::Update и Add
Полный набор ключей IPROPERTY_TEMPLATES для элемента:
| Ключ | Что задает | Пример шаблона |
|---|---|---|
| ELEMENT_META_TITLE | Тег <title> страницы | {=this.NAME} - купить в Москве |
| ELEMENT_META_DESCRIPTION | Meta description | {=this.PREVIEW_TEXT} |
| ELEMENT_META_KEYWORDS | Meta keywords | {=this.property.BRAND}, каталог |
| ELEMENT_PAGE_TITLE | H1 на детальной (не путать с meta title) | {=this.NAME} |
| ELEMENT_*_PICTURE_FILE_ALT | Alt анонс и детальной картинки | Фото {=this.NAME} |
- Модуль и поля:
Loader::includeModule('iblock'), IBLOCK_ID, NAME и другие поля элемента — как обычно. - SEO: добавьте ключ
IPROPERTY_TEMPLATESс нужными ELEMENT_META_*. - Update:
$el = new CIBlockElement; $el->Update($elementId, $arFields); - Проверка:
ElementValues::getValues()— см. следующий раздел.
<?php
use Bitrix\Main\Loader;
use Bitrix\Iblock\InheritedProperty\ElementValues;
Loader::includeModule('iblock');
$el = new CIBlockElement;
$arFields = [
'NAME' => 'Смартфон X200',
'IPROPERTY_TEMPLATES' => [
'ELEMENT_META_TITLE' => '{=this.NAME} - купить, цена, отзывы',
'ELEMENT_META_DESCRIPTION' => '{=this.PREVIEW_TEXT}',
'ELEMENT_PAGE_TITLE' => '{=this.NAME}',
],
];
if ($el->Update(4821, $arFields)) {
$seo = (new ElementValues(7, 4821))->getValues();
// $seo['ELEMENT_META_TITLE'] - вычисленный title
}
Типичная ошибка: meta в PROPERTY_VALUES - SEO-вкладка молчит. Пустая строка в IPROPERTY_TEMPLATES сбрасывает шаблон к родителю - проверьте наследование.
Делайте: обновляйте только нужные ключи. Не делайте: передавать пустые SEO-поля при импорте.
Прочитайте вычисленные SEO через ElementValues::getValues()
CIBlockElement::GetByID возвращает NAME, CODE, PREVIEW_TEXT. ELEMENT_META_TITLE там нет - это не колонка элемента, а вычисляемое SEO-поле. Для inheritedproperty elementvalues используйте D7-класс ElementValues.
<?php
use Bitrix\Iblock\InheritedProperty\ElementValues;
$values = (new ElementValues($iblockId, $elementId))->getValues();
// ELEMENT_META_TITLE, ELEMENT_META_DESCRIPTION, ELEMENT_META_KEYWORDS
// ELEMENT_PAGE_TITLE, alt/title картинок
getValues() - вычисленное значение; IPROPERTY_TEMPLATES - шаблон. Пустой шаблон элемента наследует title раздела.
Делайте: сверяйте getValues() с view-source. Не делайте: искать meta в GetByID.
Настройте наследование: инфоблок, раздел, элемент
Цепочка: инфоблок → раздел → элемент. Разделы - SectionValues::getValues(). Диагностика: админка → getValues() → view-source → кеш catalog.element.
Делайте: baseline getValues() до импорта. Не делайте: заливать пустые IPROPERTY_TEMPLATES на весь каталог.
Сравните ORM ElementTable::save() и classic API
iblocks API: $element->save() не принимает IPROPERTY_TEMPLATES.
| Способ | SEO-шаблоны | Когда выбрать |
|---|---|---|
| CIBlockElement::Update + IPROPERTY_TEMPLATES | Да | Импорт, cron, legacy-код |
| InheritedProperty\ElementTemplates::set() | Да | D7-проект, точечная запись шаблона |
| ElementTable::save() | Нет | Только NAME, CODE, ACTIVE |
| SetPropertyValues | Нет | Пользовательские свойства, не meta |
| Компонент seo.meta | Вывод на странице | Фронт, не запись в БД |
Делайте: для SEO в D7 комбинируйте save() полей и Update с IPROPERTY_TEMPLATES. Не делайте: ждать ELEMENT_META_TITLE от ElementTable::save().
Вызовите clearValues() после массового импорта
getValues() кеширует вычисление - после пакетного Update вызовите ElementValues::clearValues() и сбросьте кеш catalog.element. Иначе в API title свежий, а в браузере старый.
- Импорт: Update только для измененных ID.
- Сброс: clearValues() по списку элементов.
- Контроль: getValues() = view-source.
Делайте: clearValues() в конце cron. Не делайте: верить только true от Update.
Проверьте чек-лист: получите совпадение API и браузера
- Запись: IPROPERTY_TEMPLATES, не PROPERTY_VALUES.
- Чтение: getValues() — title, PAGE_TITLE, description.
- Кеш и браузер: clearValues() + сброс компонента, view-source = getValues().
- Alt: ELEMENT_*_PICTURE_FILE_ALT в исходнике.
Аудит обмена - контакты. Делайте: лог getValues() для 10 SKU. Не делайте: закрывать тикет по true в Update.
Автор: Максим Мольков, разработчик 1С-Битрикс.
Источники: iblocks API, IPROPERTY_TEMPLATES, ElementValues::getValues, наследуемые SEO-свойства (проверено 03.08.2026).
Частые вопросы
Что такое IPROPERTY_TEMPLATES в Битрикс?
Ключ массива $arFields в CIBlockElement::Add/Update для SEO-шаблонов элемента: ELEMENT_META_TITLE, ELEMENT_META_DESCRIPTION, ELEMENT_PAGE_TITLE и alt картинок. Это шаблоны с подстановками {=this.NAME}, не готовый title в поле NAME.
Чем ElementValues::getValues() отличается от GetByID?
GetByID читает поля b_iblock_element без SEO-meta. ElementValues::getValues($iblockId, $elementId) возвращает вычисленные ELEMENT_META_TITLE, DESCRIPTION, KEYWORDS и PAGE_TITLE с учетом наследования от раздела и инфоблока.
Как записать ELEMENT_META_TITLE через CIBlockElement::Update?
Передайте массив IPROPERTY_TEMPLATES в $arFields: ['ELEMENT_META_TITLE' => 'текст или {=this.NAME}']. Вызовите $el->Update($id, $arFields). Проверьте (new ElementValues($iblockId, $id))->getValues()['ELEMENT_META_TITLE'].
Наследуются ли SEO-поля от раздела?
Да: цепочка инфоблок → раздел → элемент. Если у элемента шаблон пустой, подставится шаблон раздела. Проверка раздела - SectionValues::getValues(). Пустая строка в IPROPERTY_TEMPLATES сбрасывает шаблон элемента к родителю.
Можно ли обновить только ELEMENT_META_DESCRIPTION?
Да: передайте в IPROPERTY_TEMPLATES только нужный ключ, например ['ELEMENT_META_DESCRIPTION' => '{=this.PREVIEW_TEXT}']. Остальные SEO-шаблоны и наследование не затронуты, если не передать пустые строки.
Почему ElementTable::save() не сохраняет SEO?
ORM save() не поддерживает IPROPERTY_TEMPLATES - только classic CIBlockElement::Update/Add или InheritedProperty\ElementTemplates::set(). Для D7-проектов комбинируйте save() полей и отдельный вызов для SEO-шаблонов.
Что дальше: создание элемента с SEO - CIBlockElement::Add → чтение карточки - GetByID → свойства - SetPropertyValues → разделы и SectionValues - CIBlockSection.