Development of a promotional website on 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
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1181
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    813
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

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 cache for anonymous users.
  • Cache-Control: public, max-age=3600 for 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