Multi-Site Structure Development on 1C-Bitrix
A single Bitrix installation can run a dozen sites with different domains, templates, content, and even languages. The SITE_ID mechanism is built into the core — every request determines which site it belongs to and pulls the right template, content, and language files. Sounds simple. In practice — cache from one site "leaks" into another, access permissions get mixed up, and the SEO module generates a sitemap with links to the wrong domain.
When Multi-Site Makes Sense
A holding company with five brands. A franchise with regional offices. A group of companies where each division has its own domain, but the product base is shared. In these cases the alternative is five separate Bitrix installations, five licenses, five servers, five 1C integrations. Multi-site on a single installation means one server, one license (starting from the "Business" edition), one admin panel.
Not justified — when the sites have zero overlap in data, audience, or business logic. In that case, tying them through a shared database only complicates deployment and increases the blast radius when something fails.
Architecture: Shared Database vs Separate
Bitrix supports two multi-site modes.
Shared database, shared files — all sites live in one MySQL database and one file system. Separation is through SITE_ID in the tables. An info block can be linked to multiple sites via b_iblock_site. A user registered on site A is automatically authorized on site B (shared b_user table, shared sessions).
Pitfalls:
-
Component cache — if you don't include
SITE_IDin the cache key, thenews.listcomponent on site B will serve data cached for site A. Standard Bitrix components usually account forSITE_ID, but custom ones don't until you add$this->arParams['CACHE_GROUPS']and includeSITE_IDingetAdditionalCacheID() - Access permissions — user groups are shared. A content manager for site A can accidentally edit an info block belonging to site B if the permission matrix isn't set up at the info block level
-
SEO module —
sitemap.xmlis generated viaseo.sitemap.run. You need to create a separate map for eachSITE_ID, otherwise site A's sitemap will include site B's URLs
Separate databases — configured in .settings.php, the connections section. Each site connects to its own database. Complete data isolation, but no more shared users or shared info blocks. Rarely used — mainly for full separation where a common admin panel is only needed for server infrastructure management.
Domains and Routing
In site settings (Settings → Product Settings → Sites) you configure:
-
Domain —
brand-a.com,brand-b.com -
Site directory — root
/or subdirectory/brand-b/ -
Default template — each site can use its own template from
local/templates/
Routing works through the core module: Bitrix matches HTTP_HOST with the SERVER_NAME field in the b_lang table. If the domain isn't found — the default site is used. For subdomains (spb.company.com, msk.company.com) the mechanism is the same — each subdomain = a separate SITE_ID.
HTTPS and CDN caveat. If nginx or Cloudflare sits in front of Bitrix, the HTTP_HOST header may arrive incorrectly. Check $_SERVER['HTTP_X_FORWARDED_HOST'] and configure SITE_SERVER_NAME in dbconn.php.
Templates: Shared vs Unique
Three strategies:
-
One template, different CSS themes. A shared HTML skeleton in
local/templates/main/, style switching viaSITE_ID. Fast, cheap, but site designs will look similar -
Separate templates.
local/templates/brand-a/,local/templates/brand-b/. Complete design freedom, but component code duplication. Solution — shared component templates inlocal/templates/.default/components/ -
Base template + inheritance. Core components and layout in the base template, custom ones in the site template.
header.phpandfooter.phpare site-specific, while component templates are reused
The third option works in practice. Header, footer, color scheme, logo — unique. Product card, news listing, contact form — shared. Maintenance savings — fix a bug in a component template once, not separately for each site.
Shared User Base
The main advantage of a shared database is single sign-on. A user registers on brand-a.com, visits brand-b.com — already authorized. This works through the shared b_user table and shared sessions.
But there's a catch. Sessions are stored in files by default — in /bitrix/sessions/. With two domains, the PHPSESSID cookie doesn't transfer between them (different domains — different cookies). Solutions:
-
Shared top-level domain —
.company.com, cookie is set on.company.com, works fora.company.comandb.company.com -
SSO via token — when navigating between domains, pass a one-time token in the URL, create a session on the receiving side. The
socialservicesmodule or a custom handler - Redis for sessions — sessions are stored centrally, but the cookie problem remains. Redis solves a different problem — horizontal scaling, not cross-domain authorization
Content: What to Share, What to Separate
Info blocks are linked to sites through admin settings. A single info block can be accessible on multiple sites. Typical scenario: product catalog — shared (SITE_ID: s1, s2, s3), news — each site has its own.
Important point — info block properties are shared. You can't add a "Promotion" property only for site A if the info block is linked to sites A, B, C. All three sites will see this property. Solution — use a multiple property of type "Site binding" and filter in the component.
Product catalog. The catalog module allows configuring different price types for different sites. A wholesale site shows wholesale prices, retail — retail prices. Stock levels — shared or separate through store bindings (b_catalog_store).
SEO settings — META templates via iblock.type.edit are set at the info block level, not the site level. For different sites with the same info block, you'll need to generate META programmatically in result_modifier.php, substituting the right values by SITE_ID.
Common Scaling Issues
-
1C Integration — the
catalog.import.1cmodule imports products into info blocks. If the catalog is shared across three sites, one import. If each site has its own catalog — three separate integrations, three profiles in 1C. With 50K+ products, each integration locks tables for 15-30 minutes. Stagger them via cron to avoid overlapping -
Search — the built-in
search.titleindexes all sites into a singleb_search_contenttable. Results are filtered bySITE_ID, but the index is shared. Across 5 sites with 100K pages each — a half-million record index, reindexing takes hours. Elasticsearch instead of built-in search — if data volume is significant -
Composite cache — the
compositemodule works correctly with multi-site, but requires separate configuration for each domain. Without it, an HTML snapshot from site A can be served on domain B
Implementation Stages
- Current infrastructure audit (3-5 days) — what data is shared, what's unique, what integrations are affected
- Structure design (1-2 weeks) — site matrix, info blocks, access permissions, templates. ER diagram of relationships
- Core setup (3-5 days) — creating sites, binding domains, configuring sessions and caching
- Template development (2-6 weeks) — depends on the number of sites and degree of design differences
- Content migration (1-2 weeks) — data transfer, binding setup, SEO audit
- Testing (1 week) — cross-site scenarios, authorization, cache, SEO
| Scale | Timeline |
|---|---|
| 2-3 sites, shared catalog, different templates | 6-10 weeks |
| 5+ sites, separate catalogs, SSO | 10-16 weeks |
| Regional network 10+ sites with 1C integration | 14-24 weeks |
Cost depends on the number of sites, how unique each one is, and integration complexity. Determined after a detailed analysis.







