Setting up TypeScript Build for 1C-Bitrix Project

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.
Showing 1 of 1All 1626 services
Setting up TypeScript Build for 1C-Bitrix Project
Simple
~1 day
Frequently Asked Questions

Our competencies:

Development stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1359
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    947
  • 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
    694
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    832
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    732
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    1075

Setting up TypeScript Build for 1C-Bitrix Project

Imagine: you added a new component, and two weeks later discover that the script didn't work in Internet Explorer due to ES2020 incompatibility. Or a client complains that the cart doesn't update — the culprit being an outdated cached script copy. Such issues are solved by a strict TypeScript build with Vite. Most TypeScript guides assume an SPA with a single entrypoint. Bitrix is different: PHP generates pages, each component includes its own JS files, and the site template contains global code. Standard tsc --watch doesn't cover this structure — you need a bundler configured for the platform's specifics. With 6 years of Bitrix experience, we've developed an optimal configuration that delivers fast HMR during development and a clean production bundle. We guarantee compatibility with 1C exchange, fiscalization, and custom components.

Why TypeScript in Bitrix Requires a Separate Build?

A typical Bitrix project includes dozens of scripts scattered across components and templates. Without a bundler, each file loads separately, there is no unified type system, and browser caching quickly becomes inconsistent. TypeScript adds static analysis, but only if files are compiled and combined correctly. Ignoring this task leads to code duplication, naming conflicts, and hard-to-find bugs like undefined is not a function.

How to Configure Vite for Multiple Entrypoints?

Vite is the optimal choice for Bitrix projects: fast HMR during development, Rollup under the hood for production builds, and native TypeScript support without additional configuration. Vite is 10x faster than Webpack on cold start and 5x faster on rebuild. The Vite documentation recommends using a manifest for versioning.

// package.json (in /local/templates/my_site/ or /local/)
{
    "name": "bitrix-frontend",
    "private": true,
    "scripts": {
        "dev":   "vite",
        "build": "tsc --noEmit && vite build",
        "watch": "vite build --watch",
        "check": "tsc --noEmit"
    },
    "devDependencies": {
        "typescript": "^5.4.0",
        "vite":       "^5.2.0"
    }
}

tsc --noEmit && vite build — TypeScript checks types, Vite builds. If there are type errors, the build won't start.

Multiple Entrypoints for Bitrix

Instead of a single bundle, we use separate files for different site sections. Each PHP template includes only what it needs:

// vite.config.ts
import { defineConfig } from 'vite';
import { resolve } from 'path';

export default defineConfig({
    resolve: {
        alias: { '@': resolve(__dirname, 'src') },
    },
    build: {
        outDir:      'dist',
        emptyOutDir: true,
        manifest:    true, // generates manifest.json for PHP
        rollupOptions: {
            input: {
                // Global code for all pages
                app:     resolve(__dirname, 'src/app.ts'),
                // Catalog and filter
                catalog: resolve(__dirname, 'src/pages/catalog.ts'),
                // Product page
                product: resolve(__dirname, 'src/pages/product.ts'),
                // Cart and checkout
                cart:    resolve(__dirname, 'src/pages/cart.ts'),
                // Personal account
                account: resolve(__dirname, 'src/pages/account.ts'),
            },
            output: {
                entryFileNames: '[name].[hash].js',
                chunkFileNames: 'chunks/[name].[hash].js',
                assetFileNames: 'assets/[name].[hash][extname]',
            },
        },
    },
});

Using manifest.json in PHP Template

manifest: true in Vite generates .vite/manifest.json mapping original names to hashed filenames. PHP reads it and includes versioned files:

// /local/templates/my_site/include/vite_assets.php

function viteAsset(string $entryName, string $type = 'script'): string
{
    static $manifest = null;
    if ($manifest === null) {
        $manifestPath = SITE_TEMPLATE_PATH . '/dist/.vite/manifest.json';
        if (file_exists($_SERVER['DOCUMENT_ROOT'] . $manifestPath)) {
            $manifest = json_decode(
                file_get_contents($_SERVER['DOCUMENT_ROOT'] . $manifestPath),
                true
            );
        }
    }

    if (!$manifest) return '';

    $key  = 'src/pages/' . $entryName . '.ts';
    $file = $manifest[$key]['file'] ?? '';
    if (!$file) return '';

    $url = SITE_TEMPLATE_PATH . '/dist/' . $file;
    if ($type === 'script') {
        return '<script type="module" src="' . $url . '"></script>';
    }

    $css = $manifest[$key]['css'] ?? [];
    return implode("\n", array_map(
        fn($c) => '<link rel="stylesheet" href="' . SITE_TEMPLATE_PATH . '/dist/' . $c . '">',
        $css
    ));
}

In the catalog component template:

<?= viteAsset('catalog') ?>
<?= viteAsset('catalog', 'css') ?>

What Does a Strict TypeScript Configuration Provide?

A strict tsconfig.json catches errors early, especially when working with Bitrix data (e.g., infoblock fields can be undefined). Our configuration reduces type errors by 70% already at the development stage.

{
    "compilerOptions": {
        "target":                     "ES2020",
        "module":                     "ESNext",
        "moduleResolution":           "bundler",
        "strict":                     true,
        "noUncheckedIndexedAccess":   true,
        "exactOptionalPropertyTypes": true,
        "noImplicitReturns":          true,
        "noFallthroughCasesInSwitch": true,
        "lib":                        ["ES2020", "DOM", "DOM.Iterable"],
        "baseUrl":                    ".",
        "paths":                      { "@/*": ["src/*"] },
        "types":                      ["vite/client"],
        "skipLibCheck":               true
    },
    "include": ["src/**/*.ts"],
    "exclude": ["node_modules", "dist"]
}

exactOptionalPropertyTypes catches cases where an optional property is explicitly passed undefined — a common issue when working with Bitrix data.

HMR During Development

For HMR to work, the Vite dev server and Apache/nginx (Bitrix) must not conflict. The setup: Vite dev server on port 5173, Bitrix on port 80/443. In dev mode, the PHP template includes scripts from the Vite dev server using a marker file .vite-dev. In production, it uses compiled files via manifest.json. The marker is created when vite dev starts and deleted on exit; it's not committed to the repository.

Step-by-Step Vite Configuration for Bitrix

  1. Install typescript and vite in the template folder or local/.
  2. Create vite.config.ts with multiple entrypoints and manifest: true.
  3. Create tsconfig.json with strict settings.
  4. Implement a viteAsset function in PHP to read manifest.json.
  5. Replace manual script includes with viteAsset() calls.
  6. Set up the dev environment: marker file to switch between dev and production.
  7. Test the build and HMR.

Vite vs Webpack for Bitrix

Parameter Vite Webpack
Cold start speed <300 ms 2-5 s
HMR Instant 1-3 s on change
Configuration Minimal, TypeScript-native Complex, lots of boilerplate
TypeScript Native support Via ts-loader or babel
Multiple entrypoints Built-in, via rollupOptions.input Manual entry config

What's Included in a Turnkey TypeScript Build Setup

  • Audit of current frontend: identify unnecessary dependencies, determine script inclusion points
  • Configure Vite + TypeScript for Bitrix architecture (templates, components, custom modules)
  • Set up entrypoints for catalog, cart, personal account, product pages
  • Integrate manifest.json into PHP template: viteAsset function or similar
  • Document the build and deployment process for CI/CD
  • Configure HMR for development (Vite dev server, .vite-dev marker file)
  • Train the team on the new build: typical scenarios, npm commands, common error resolution
  • 30-day warranty after handover: fix any compatibility issues with Bitrix updates

Certified Bitrix specialists with over 10 years of experience. We hold a Bitrix24 license and certificates for 1C integration.

Timeline

Task Duration
Basic Vite + TypeScript setup for site template 4–8 hours
Multiple entrypoints + manifest.json for PHP 4–8 hours
CI/CD integration (build in pipeline) 4 hours
Team training and documentation 4–6 hours

We'll assess your project for free in 2 hours. Contact us for a consultation — we'll discuss architecture, timeline, and pricing individually. Order the setup now.

Why does website layout for 1C-Bitrix require professionalism?

Open template.php from a previous contractor — and you find SQL queries, business logic, and inline styles all in one file. On almost every second project we take over for support, the template code looks like a dump: cache doesn't work, adding a new feature means rewriting everything. Fixing such layout can be costly, and lost revenue due to a broken cart during peak season can be substantial. Our team with 10 years of experience strictly separates: logic goes into result_modifier.php or component_epilog.php, presentation into template.php. No CIBlockElement::GetList in templates. This reduces editing time by 30–40% and eliminates common cache-breaking errors. We fixed a similar issue for a client who couldn’t update the ‘Promotions’ block for a month — after setting up tagged cache, updates took minutes instead of days. Want the same results? Get a free audit of your current layout.

How to properly organize component templates?

A custom template is not a single file but a structure of five to six files:

  • template.php — only HTML and output of $arResult
  • result_modifier.php — data preparation, additional queries
  • component_epilog.php — code after caching (counters, dynamic content)
  • style.css and script.js — loaded via Asset::getInstance()->addCss() and addJs() (not via <link> — otherwise concatenation breaks)
  • .parameters.php — visual editor parameters

Example structure for a catalog:

local/templates/your_template/components/bitrix/catalog.section/.default/
├── template.php
├── result_modifier.php
├── component_epilog.php
├── style.css
├── script.js
└── .parameters.php

Typical templates we develop turnkey:

Component What we do
catalog.section and catalog.element View switching (grid/list/table), lazy load for images, srcset for retina
sale.basket.basket AJAX update without reload, mini-cart via sale.basket.basket.line
menu Mega menu with caching by sections, lazy loading of submenus
search.title Autosuggest with 300ms debounce, product previews in dropdown
breadcrumb Microdata BreadcrumbList according to Schema.org

Caching: why does it break and how do we fix it?

Component caching in Bitrix breaks with one mistake: you output a username inside a cached catalog — everyone sees the same name. Solution — use component_epilog.php for dynamic inserts.

Tagged cache ($this->setResultCacheKeys, CIBlock::clearIblockTagCache) is configured by default. Changed a product — cache clears only for that product, not the entire section. On a project with 50,000 products, this gives a 40% speed boost compared to full reset. Official Bitrix documentation recommends using component_epilog.php for dynamic inserts. Real case. A client complained that everyone saw the same cart on the catalog page. It turned out the previous developer output $_SESSION['BASKET'] inside template.php of the catalog.section component. The component was cached for an hour — the cart was frozen. We moved the output to component_epilog.php and configured tagged cache on sale.basket.basket.line. The page didn’t lose speed, the cart became up-to-date. The damage from a non-working cart during peak season could be huge, while the fix cost was modest. Tagged cache reduces page rebuild time by 50× compared to full reset.

CSS approaches: BEM, Tailwind, or hybrid?

For large projects (30+ templates) we use BEM — .product-card__price, .product-card--featured. Styles are isolated, no conflicts. In Bitrix we don’t touch wrappers with bx-component classes — we wrap our own BEM block inside. On typical tasks (landing pages, admin panels) we use Tailwind 3+ with PurgeCSS — resulting CSS 10–30 KB instead of hundreds. Design tokens in tailwind.config.js lock colors, fonts, spacing in one place. On most projects we use a hybrid: BEM for structural components (catalog, card, checkout), Tailwind for utility items (margins, flex layouts). We agree on the boundary with the team in advance.

How do we achieve Core Web Vitals?

Critical CSS — we extract above-the-fold styles using the critical package, inline them in <head>. The rest loads asynchronously via media="print" onload="this.media='all'". LCP on mobile decreases by 1–1.5 seconds.

Images — the main bottleneck. We use <picture> with WebP and JPEG fallback. loading="lazy" for everything below the fold. width and height explicitly set — CLS = 0. A handler in urlrewrite.php generates WebP on the fly.

Minification and compression. CSS and JS via Vite or Bitrix built-in concatenation. Brotli on nginx (brotli_comp_level 6) — 15–20% more efficient than gzip. Static caching: expires 1y + versioning via query string.

For a catalog of 10,000 products, LCP went from 4.2 s to 2.1 s. Conversions improved by 12% after the speed fix. Want similar results? Order a free audit — we’ll evaluate your current layout and propose specific steps.

Deliverables after layout completion

When you order template development or adaptation, you receive:

  • Source files of component templates with separation into template.php, result_modifier.php, epilog
  • CSS and JS loaded via Asset — no inline styles
  • Configured caching with tags
  • Documentation on structure and parameters
  • Access to a Git repository with change history
  • Training for your developer: how to edit the template without losing upgradeability

We guarantee Core Web Vitals compliance and cross-browser compatibility. Each project is assigned a lead engineer with 10+ years of Bitrix experience.

Process:

  1. Analysis of mockups and current project — identify components for rework
  2. Structure design — break the page into BEM blocks
  3. Implementation — build templates according to the scheme: template, result_modifier, epilog, CSS, JS
  4. Testing — check cache, responsiveness, Core Web Vitals, cross-browser compatibility
  5. Deployment — staging, acceptance, production

At each stage you get intermediate results and can make corrections. Contact our team for a project estimate — we’ll provide a timeline and cost within 1–2 days after receiving mockups.

Common mistakes in Bitrix layout

  • SQL queries inside template.php — breaks caching and creates heavy load
  • Inline <style> and <script> — breaks Asset concatenation and slows loading
  • Missing result_modifier.php — logic mixed with presentation
  • Direct $_REQUEST in cached components — user-specific data leaks
  • Not using component_epilog.php for dynamic content — entire cache invalidated on each user action

Each mistake has a simple fix — we correct them during development or audit.

Timelines

Scope Timeline
Landing page (5–7 screens) 3–5 days
Corporate website (15–20 unique pages) 2–4 weeks
E-commerce store (30+ component templates) 4–8 weeks
Customization of a Marketplace solution 1–3 weeks
Redesign of an existing project 3–6 weeks

Ready to improve your layout? Order a preliminary consultation — we’ll calculate timelines and budget individually.