Setting Up Video Reviews in Product Card in 1C-Bitrix
Product card loads YouTube-iframe, user only understands review exists then. First frame not shown, player slows mobile LCP by 2–4 seconds, "Yandex.Metrica" shows 80% leave before autoplay. This isn't video problem — how Bitrix embeds media in card.
Where Video Stored in Iblock
Bitrix lacks native "video" field type in standard properties. Video review usually stored in one of three places:
- Property type
S(string) with YouTube/Vimeo URL — most common - Property type
F(file) — direct mp4 upload,b_iblock_element_propertytable - Detail description field (HTML/TinyMCE) — video buried in
b_iblock_element.DETAIL_TEXT
For bitrix.catalog right way — separate property with symbol code like VIDEO_URL linked to catalog iblock. Query via CIBlockElement::GetProperty() or D7 \Bitrix\Iblock\ElementPropertyTable:
$props = \Bitrix\Iblock\ElementPropertyTable::getList([
'filter' => ['IBLOCK_ELEMENT_ID' => $elementId, 'CODE' => 'VIDEO_URL'],
'select' => ['VALUE'],
])->fetch();
Lazy-Load Preview Instead of Iframe
Main problem — <iframe src="https://www.youtube.com/embed/..."> blocks main thread. Solution: render custom preview via YouTube thumbnail API (https://img.youtube.com/vi/{VIDEO_ID}/hqdefault.jpg) and replace with iframe only on click.
In catalog.element template (template.php):
<?php if (!empty($arResult['PROPERTIES']['VIDEO_URL']['VALUE'])): ?>
<?php
$videoUrl = $arResult['PROPERTIES']['VIDEO_URL']['VALUE'];
preg_match('/(?:v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/', $videoUrl, $matches);
$videoId = $matches[1] ?? '';
?>
<div class="product-video" data-video-id="<?= htmlspecialchars($videoId) ?>">
<img src="https://img.youtube.com/vi/<?= $videoId ?>/hqdefault.jpg"
loading="lazy" alt="Product Review" class="video-preview">
<button class="video-play-btn" aria-label="Play Video">▶</button>
</div>
<?php endif; ?>
JavaScript on click replaces div with autoplay=1 iframe. Removes extra HTTP request to YouTube on page load and reduces page weight by 500–800 KB (YouTube loads own JS bundle with any iframe).
Caching and Invalidation
catalog.element template cached via CBitrixComponent::StartResultCache(). If video changes in admin, cache not cleared auto — either write $this->AbortResultCache() for empty VIDEO_URL or add cache tag:
$GLOBALS['CACHE_MANAGER']->RegisterTag('iblock_id_' . $iblockId);
Then on element save event (OnAfterIBlockElementUpdate) cache clears correctly.
Video in Product Variations (Trade Offers)
If SKU-variants (table b_catalog_product, type P — offer) have different videos, load property not parent element but specific offer. Standard catalog.element doesn't do this — returns parent properties only. Solution: AJAX request on SKU change to custom action or component returning VIDEO_URL for chosen offerId.
In bitrix:catalog.element component parameter OFFER_IBLOCK_ID points to offers iblock — that's where to fetch media properties.
Structured Data for Video
Google indexes card video with VideoObject markup. Bitrix doesn't generate automatically. Add to template manually:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "VideoObject",
"name": "<?= htmlspecialcharsEx($arResult['NAME']) ?>",
"thumbnailUrl": "https://img.youtube.com/vi/<?= $videoId ?>/hqdefault.jpg",
"uploadDate": "<?= date('Y-m-d') ?>",
"embedUrl": "https://www.youtube.com/embed/<?= $videoId ?>"
}
</script>
Gives chance to appear in video carousel without third-party plugins.







