Developing a Promo Site on 1C-Bitrix
A promo site is a short-lived or permanent site for a specific product, promotion, or event. Its main goal is conversion: registration, an enquiry, or a purchase. Technically, a promo site on Bitrix most often means a one-pager (landing page) with several sections, lead capture forms, and optionally an integration with Bitrix24.
When to Use Bitrix for a Promo Site Rather Than a Website Builder
Bitrix is chosen for a promo site if:
- The main site is already on Bitrix — the promo is hosted on a subdomain or in a folder, using the same CMS.
- Integration with CRM (Bitrix24) is needed without extra middleware — forms create leads directly.
- The promo site is planned to be reused multiple times with different content (promotions, events).
- The promo content must be editable in the Bitrix editor without a developer.
Promo Site Architecture
Two approaches are possible for a promo site on Bitrix:
1. A separate template on the main site. A new template is created in /local/templates/promo_EVENTNAME/. In header.php and footer.php — a minimal wrapper, without the main navigation menu. The page /promo/event-name/index.php applies this template via $APPLICATION->SetTemplate().
2. A separate site within the composite site. If the promo is on the subdomain promo.example.com — a new site is created in the admin area (Settings → Sites → Site List). Its own template, its own settings, its own mail events.
Editable Sections via Info Block
So that a marketer can change promo content without a developer — editable blocks are placed via the promo_sections info block:
// Promo page sections
$sections = \CIBlockElement::GetList(
['SORT' => 'ASC'],
[
'IBLOCK_ID' => PROMO_SECTIONS_IBLOCK_ID,
'ACTIVE' => 'Y',
'PROPERTY_PROMO_ID' => $promoId,
],
false,
false,
['ID', 'NAME', 'CODE', 'DETAIL_TEXT', 'PROPERTY_SECTION_TYPE', 'PROPERTY_BG_IMAGE', 'PROPERTY_CTA_TEXT', 'PROPERTY_CTA_URL']
);
Section element properties: section type (hero, features, testimonials, cta, faq), background image, CTA button text, button URL. In the template — a switch on SECTION_TYPE that includes the corresponding include:
while ($section = $sections->GetNext()) {
$sectionType = $section['PROPERTY_SECTION_TYPE_VALUE'];
$sectionFile = __DIR__ . '/sections/' . $sectionType . '.php';
if (file_exists($sectionFile)) {
include $sectionFile;
}
}
Lead Capture Forms
A promo site has multiple conversion points: a form in the hero section, a form at the bottom of the page, and a popup form when the user attempts to leave (exit-intent). All of them send data to a single handler:
// /local/ajax/promo_lead.php
\Bitrix\Main\Loader::includeModule('crm');
$promoId = htmlspecialchars($_POST['promo_id'] ?? '');
$name = htmlspecialchars(trim($_POST['name'] ?? ''));
$phone = htmlspecialchars(trim($_POST['phone'] ?? ''));
$email = htmlspecialchars(trim($_POST['email'] ?? ''));
// Source is recorded for analytics
$source = htmlspecialchars($_POST['form_position'] ?? 'unknown'); // hero | bottom | popup
if (empty($phone) && empty($email)) {
echo json_encode(['error' => 'Please provide a phone number or email']);
exit;
}
$lead = new \CCrmLead(false);
$leadId = $lead->Add([
'TITLE' => 'Promo: ' . $promoId . ' — ' . $name,
'NAME' => $name,
'PHONE' => [['VALUE' => $phone, 'VALUE_TYPE' => 'WORK']],
'EMAIL' => [['VALUE' => $email, 'VALUE_TYPE' => 'WORK']],
'SOURCE_ID' => 'WEB',
'SOURCE_DESCRIPTION' => 'Promo: ' . $promoId . ', form: ' . $source,
'UTM_SOURCE' => $_COOKIE['utm_source'] ?? '',
'UTM_MEDIUM' => $_COOKIE['utm_medium'] ?? '',
'UTM_CAMPAIGN' => $_COOKIE['utm_campaign'] ?? '',
]);
echo json_encode(['success' => (bool)$leadId]);
UTM tags. When the promo page is visited — save UTM parameters in a cookie via JS (30 minutes). When submitting a form — pass them with the request. In Bitrix24 leads the fields UTM_SOURCE, UTM_MEDIUM, UTM_CAMPAIGN, UTM_TERM, UTM_CONTENT are available — use them.
Countdown Timer
An important promo element — a countdown timer to the end of the promotion. Implemented in JS using server time (not the browser's local time):
// In the PHP template, pass the server end date
$promoEndDate = '2026-04-01T23:59:59+03:00';
echo '<script>window.PROMO_END_DATE = "' . $promoEndDate . '";</script>';
// Timer component
function startCountdown(endDateStr) {
const endDate = new Date(endDateStr);
const timer = setInterval(() => {
const now = new Date();
const diff = endDate - now;
if (diff <= 0) {
clearInterval(timer);
document.getElementById('timer').textContent = 'Promotion ended';
return;
}
const days = Math.floor(diff / 86400000);
const hours = Math.floor((diff % 86400000) / 3600000);
const minutes = Math.floor((diff % 3600000) / 60000);
const seconds = Math.floor((diff % 60000) / 1000);
document.getElementById('timer-days').textContent = String(days).padStart(2, '0');
document.getElementById('timer-hours').textContent = String(hours).padStart(2, '0');
document.getElementById('timer-minutes').textContent = String(minutes).padStart(2, '0');
document.getElementById('timer-seconds').textContent = String(seconds).padStart(2, '0');
}, 1000);
}
A/B Testing
A/B testing is critical for promo sites. A simple implementation without external services: divide visitors into groups via a cookie.
// Determine the variant for the user
if (!isset($_COOKIE['promo_variant'])) {
$variant = rand(0, 1) ? 'A' : 'B';
setcookie('promo_variant', $variant, time() + 86400 * 30, '/');
} else {
$variant = $_COOKIE['promo_variant'];
}
// Include the appropriate template
$templateFile = __DIR__ . '/variants/' . $variant . '.php';
include $templateFile;
Conversion results — via a separate counter in the table b_local_promo_ab_stats with fields: PROMO_ID, VARIANT, VIEWS, CONVERSIONS.
Caching and Performance
A promo site can receive peak traffic (from a mailing, advertising campaign). Set this up in advance:
- Full-page caching via
nginx FastCGI cachefor anonymous users. -
Cache-Control: public, max-age=3600for static assets. - Pre-warming the cache after deployment.
- Server-side AJAX rate limiting (nginx:
limit_req_zone).
Development Timelines
| Option | Composition | Duration |
|---|---|---|
| Landing from a ready-made mockup | Layout + form + lead in CRM | 3–5 days |
| With editable content | + Section info block, admin panel management | 5–8 days |
| Full-featured promo | + Timer, A/B test, UTM analytics | 8–14 days |







