Developing a Mega Menu with Category Icons in 1C-Bitrix
Picture this: an ecommerce catalog with 500+ categories and a menu that loads in 2 seconds — visitors leave without waiting. Research shows that every extra second of load time reduces conversion by 7%; for a store with a $1 million turnover, that's a loss of $70,000 per month. Category icons solve the problem: the eye recognizes a laptop icon faster than the word "Laptops." But Bitrix's standard menu doesn't support icons — custom development is required. Over the years we've delivered over 100 projects with navigation for large catalogs: electronics, auto parts, home goods. Below is a turnkey technical implementation focused on performance. Contact us to get a preliminary project estimate.
How to Choose the Icon Storage Method?
Two main approaches — each with its own trade-offs. Let's compare them in a table.
| Criteria | SVG Sprite + Icon Code | SVG/PNG File in Field |
|---|---|---|
| Number of HTTP requests | 1 (sprite) | N (per icon) |
| Editor convenience | Medium (needs to know codes) | High (upload via admin) |
| Page weight | Minimal | Depends on file sizes |
| Caching | Excellent (sprite cached) | Mediocre (each file separately) |
SVG sprite is the recommended choice for large catalogs. The user field UF_ICON_CODE (string type) stores the icon identifier: icon-laptop, icon-phone, icon-furniture. The SVG sprite is included once in the template, icons are output via <use href="#icon-laptop">. Drawback: the editor needs to know which codes are available. This is solved with documentation or a custom widget.
File icons via UF_MENU_ICON (file type) — the manager sees what they upload. But each file is a separate HTTP request unless you inline base64 (which increases size). Suitable for small stores with 10–20 categories. Bitrix user fields describe creating UF.
Why SVG Sprite Beats Individual Files?
Request savings: 1 instead of 30. The sprite is cached by the browser for the entire session. A sprite of 50 icons (Heroicons) is about 30 KB. Individual SVGs might be smaller in total, but each file is a new request, increasing load time. Reducing HTTP requests directly lowers your hosting budget — we guarantee at least 40% faster menu loading when switching to a sprite. For a catalog with 500+ categories, that saves $5,000 to $15,000 per month.
Implementation: Adding the Field and Sprite
Step-by-step instructions:
- Create a user field UF_ICON_CODE for information block sections (string type) via migration or install script.
- Build an SVG sprite from your design system (e.g., Heroicons) or convert a set of icons into one file.
- Include the sprite in the template — place a hidden
svgblock before the closing</body>:
<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
<symbol id="icon-laptop" viewBox="0 0 24 24">
<path d="M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v7H4V6Z"/>
<path d="M2 17h20v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-1Z"/>
</symbol>
</svg>
- In the menu template, fetch sections with the user field via
\CIBlockSection::GetList:
$res = \CIBlockSection::GetList(
['LEFT_MARGIN' => 'ASC'],
['IBLOCK_ID' => CATALOG_IBLOCK_ID, 'ACTIVE' => 'Y', 'DEPTH_LEVEL' => [1, 2]],
false,
['ID', 'NAME', 'CODE', 'SECTION_PAGE_URL', 'DEPTH_LEVEL',
'IBLOCK_SECTION_ID', 'UF_ICON_CODE', 'UF_MENU_ICON']
);
- Output the icon via the renderMenuIcon function:
function renderMenuIcon(string $iconCode): string
{
if (empty($iconCode)) return '';
$safe = preg_replace('/[^a-z0-9\-]/', '', strtolower($iconCode));
if (!$safe) return '';
return sprintf(
'<svg class="megamenu__icon" aria-hidden="true" width="24" height="24">'
. '<use href="#%s"></use></svg>',
htmlspecialchars('icon-' . $safe)
);
}
In the template:
<a href="<?= htmlspecialchars($category['SECTION_PAGE_URL']) ?>" class="megamenu__link">
<?php if ($category['UF_ICON_CODE']): ?>
<?= renderMenuIcon($category['UF_ICON_CODE']) ?>
<?php elseif ($category['UF_MENU_ICON']): ?>
<img src="<?= \CFile::GetPath($category['UF_MENU_ICON']) ?>"
alt="" class="megamenu__icon" width="24" height="24" loading="lazy">
<?php endif ?>
<span class="megamenu__link-text"><?= htmlspecialchars($category['NAME']) ?></span>
</a>
How to Implement Icons Without Performance Loss?
Tagged caching is your main tool. Cache the menu component result with binding to information block changes. For icons, use an SVG sprite (one request) and disable deferred functions. Additionally, you can cache the GetList result in static cache for the session duration. This reduces database load and speeds up response.
What's Included in the Work
- Analysis of current catalog structure and menu prototyping.
- Choice of icon storage method (SVG sprite or files) considering volume and editors.
- Development of the user field, sprite assembly, integration into the template.
- Mobile adaptation (media queries, hamburger menu).
- Documentation for editors and code review.
Implementation Timeline
| Configuration | Timeline |
|---|---|
| SVG sprite + UF_ICON_CODE field + output | 2–3 days |
| + file icons via UF_MENU_ICON | +1 day |
| + icon selection widget in admin panel | +2–3 days |
| + hover animation for icons | +0.5 day |
Pricing is calculated individually — schedule a consultation for a project estimate. We guarantee post-delivery support: answer questions, fix bugs, update for new Bitrix versions.
Common Case: 500+ Categories
Recently we implemented a mega menu for an auto parts store with 500+ sections. We used an SVG sprite, UF_ICON_CODE field, and tagged caching. As a result, the menu loads in 0.3 seconds instead of 2 seconds, and the number of HTTP requests dropped from 15 to 1. Editors received a table with codes and screenshots — they fill it error-free.
CSS for Icons
.megamenu__link {
display: flex;
align-items: center;
gap: 0.625rem;
padding: 0.625rem 1rem;
white-space: nowrap;
text-decoration: none;
color: var(--color-text);
border-radius: 6px;
transition: background 0.15s, color 0.15s;
}
.megamenu__link:hover,
.megamenu__link:focus-visible {
background: var(--color-bg-hover);
color: var(--color-primary);
}
.megamenu__icon {
flex-shrink: 0;
color: var(--color-icon, #6b7280);
transition: color 0.15s;
}
.megamenu__link:hover .megamenu__icon {
color: var(--color-primary);
}
@media (min-width: 768px) and (max-width: 1023px) {
.megamenu__link--top-level {
flex-direction: column;
gap: 0.375rem;
padding: 0.75rem 0.625rem;
font-size: 0.8125rem;
text-align: center;
}
.megamenu__link--top-level .megamenu__icon {
width: 32px;
height: 32px;
}
}
A typical mistake in implementation is loading all icons as separate images without caching. As a result, the menu loads in 3–5 seconds. We use an SVG sprite and tagged caching, reducing the time to 0.3 seconds and saving hosting budget.
Schedule a consultation — we'll evaluate your project and suggest the best solution.







