Setting up an RSS feed 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

Configuring RSS Feed in 1C-Bitrix

RSS remains a relevant format for news aggregators, monitoring services, and content syndication. Bitrix generates RSS through the bitrix:rss.out component, but by default the feed has several problems: incorrect encodings, missing CDATA wrappers for HTML content, incorrect dates, no Atom support.

Built-in RSS Component

Component bitrix:rss.out is available in "Content" → "RSS Feed" in the visual page editor. The RSS page is usually located at /rss.php or /news/rss/.

Minimal RSS page code:

<?php
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/header.php");
$APPLICATION->SetPageProperty("robots", "noindex");

$APPLICATION->IncludeComponent(
    "bitrix:rss.out",
    "",
    [
        "IBLOCK_TYPE" => "news",
        "IBLOCK_ID" => "3",
        "SECTION_ID" => "",
        "SECTION_CODE" => "",
        "FIELD_IMAGE" => "Y",
        "ELEMENT_COUNT" => "20",
        "SORT_FIELD" => "ACTIVE_FROM",
        "SORT_ORDER" => "DESC",
        "CACHE_TYPE" => "A",
        "CACHE_TIME" => "360",
        "SET_TITLE" => "N",
        "CHARSET" => "utf-8"
    ]
);

require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/footer.php");

MIME Type and Headers Issue

By default the RSS page is served with Content-Type: text/html. RSS aggregators expect application/rss+xml. Solution — set the header at the beginning of the page, BEFORE calling header.php:

<?php
define("NO_KEEP_STATISTIC", true);
define("NO_AGENT_CHECK", true);

header("Content-Type: application/rss+xml; charset=utf-8");
header("X-Robots-Tag: noindex");

require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");

// Component without header.php and footer.php
$APPLICATION->IncludeComponent("bitrix:rss.out", "", [...]);

Configuring RSS Template for HTML Content

The standard component template doesn't wrap DETAIL_TEXT in CDATA. Aggregators can't parse HTML inside XML. Copy the template for customization:

cp -r /var/www/bitrix/bitrix/components/bitrix/rss.out/templates/.default/ \
      /var/www/bitrix/local/components/bitrix/rss.out/templates/.default/

In the template's template.php file, find description output and wrap it in CDATA:

// Was:
<?= $arItem["DETAIL_TEXT"] ?>

// Now:
<![CDATA[<?= strip_tags($arItem["DETAIL_TEXT"]) ?>]]>

// Or with HTML preserved (for aggregators supporting content:encoded):
<content:encoded><![CDATA[<?= $arItem["DETAIL_TEXT"] ?>]]></content:encoded>

Add namespace for content to <channel> element:

<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:atom="http://www.w3.org/2005/Atom">

Correct Date Format

RSS requires date in RFC 2822 format: Mon, 15 Mar 2024 12:00:00 +0300. Bitrix returns date in d.m.Y H:i:s format. In the component template:

// Convert Bitrix date to RFC 2822
$bitrixDate = $arItem["ACTIVE_FROM"]; // "15.03.2024 12:00:00"
$timestamp = MakeTimeStamp($bitrixDate, "DD.MM.YYYY HH:MI:SS");
$rfc2822Date = date(DATE_RSS, $timestamp);

RSS with Images (media:content)

For aggregators showing image previews — add media:content:

<!-- namespace in <rss>: xmlns:media="http://search.yahoo.com/mrss/" -->

<?php if ($arItem["PREVIEW_PICTURE"]): ?>
<?php $pic = CFile::GetFileArray($arItem["PREVIEW_PICTURE"]); ?>
<media:content url="<?= SITE_SERVER_NAME . $pic["SRC"] ?>"
               medium="image"
               type="<?= $pic["CONTENT_TYPE"] ?>" />
<?php endif; ?>

RSS Caching

Each RSS request without cache runs GetList on the infoblock. Cache component through managed cache:

"CACHE_TYPE" => "A",     // automatic cache
"CACHE_TIME" => "3600",  // 1 hour

Additionally in Nginx — proxy-level caching:

location ~* /rss(\.php)?$ {
    proxy_cache_valid 200 15m;
    add_header X-Cache-Status $upstream_cache_status;
}

Feed Validation

Validate RSS for correctness:

# Via curl + xmllint
curl -s https://example.ru/rss/ | xmllint --noout -

# Or online: https://validator.w3.org/feed/

Common errors: unclosed tags in DETAIL_TEXT, forbidden characters (control ASCII 0x00–0x1F, except tab/LF/CR), missing <lastBuildDate> in channel header.