Skip to the content.
← Back to UI Components ← Back to Table of Contents

9.2 Bootstrap Icons Integration

Last Updated: December 3, 2025

This document explains Bootstrap Icons integration, configuration, and usage in KMP templates.

Overview

KMP integrates Bootstrap Icons 1.11.3, a comprehensive icon set with 2000+ SVG icons. Icons provide visual consistency and improve user interface clarity throughout the application.

Bootstrap Icons Features

Configuration

File Structure

Bootstrap Icons are stored in the webroot:

webroot/assets/bootstrap-icons/
├── font/
│   ├── bootstrap-icons.json      # Icon metadata and SVG paths
│   ├── bootstrap-icons.ttf       # TrueType font format
│   ├── bootstrap-icons.woff      # Web Open Font Format
│   └── bootstrap-icons.woff2     # Web Open Font Format 2 (compressed)
└── svg/
    ├── [icon-name].svg           # Individual icon SVG files
    └── ...

Application Configuration

Icon sets are configured in config/app.php:

'Icon' => [
    'sets' => [
        'bs' => [
            'class' => BootstrapIcon::class,
            'path' => WWW_ROOT . 'assets/bootstrap-icons/font/bootstrap-icons.json',
        ],
    ],
],

Configuration Parameters:

Parameter Type Purpose
class string Icon rendering class (BootstrapIcon::class)
path string Path to icon JSON file with metadata
set string Icon set identifier (bs for Bootstrap)

Using Icons in Templates

Basic Icon Rendering

In CakePHP templates:

<?= $this->Icon->render('star-fill', ['set' => 'bs']) ?>
<?= $this->Icon->render('person', ['set' => 'bs']) ?>
<?= $this->Icon->render('search', ['set' => 'bs']) ?>

Renders as inline SVG:

<svg class="icon" width="1em" height="1em" viewBox="0 0 16 16">
  <path fill="currentColor" d="..."/>
</svg>

Icon with CSS Classes

Apply custom CSS classes:

<?= $this->Icon->render('star-fill', [
    'set' => 'bs',
    'class' => 'text-warning'
]) ?>

<?= $this->Icon->render('person', [
    'set' => 'bs',
    'class' => 'icon-large text-primary'
]) ?>

Icon Sizing

Control icon size via CSS classes or inline styles:

<!-- Small icon (14px) -->
<?= $this->Icon->render('search', [
    'set' => 'bs',
    'class' => 'icon-sm'  // 14px
]) ?>

<!-- Medium icon (20px, default) -->
<?= $this->Icon->render('edit', [
    'set' => 'bs'
]) ?>

<!-- Large icon (24px) -->
<?= $this->Icon->render('download', [
    'set' => 'bs',
    'class' => 'icon-lg'  // 24px
]) ?>

<!-- Extra large icon (32px) -->
<?= $this->Icon->render('info-circle', [
    'set' => 'bs',
    'class' => 'icon-xl'  // 32px
]) ?>

Icon with Colors

Use Bootstrap color classes:

<!-- Primary color -->
<?= $this->Icon->render('check-circle', [
    'set' => 'bs',
    'class' => 'text-primary'
]) ?>

<!-- Success color -->
<?= $this->Icon->render('check', [
    'set' => 'bs',
    'class' => 'text-success'
]) ?>

<!-- Warning color -->
<?= $this->Icon->render('exclamation-triangle', [
    'set' => 'bs',
    'class' => 'text-warning'
]) ?>

<!-- Danger color -->
<?= $this->Icon->render('x-circle', [
    'set' => 'bs',
    'class' => 'text-danger'
]) ?>

<!-- Custom color via CSS -->
<?= $this->Icon->render('star', [
    'set' => 'bs',
    'style' => 'color: #ff6b6b;'
]) ?>

Icons in Buttons

Include icons in button elements:

<!-- Button with icon and text -->
<button class="btn btn-primary">
    <?= $this->Icon->render('download', ['set' => 'bs', 'class' => 'me-2']) ?>
    Download
</button>

<!-- Icon-only button -->
<button class="btn btn-sm btn-outline-secondary" title="Edit">
    <?= $this->Icon->render('pencil', ['set' => 'bs']) ?>
</button>

<!-- Button group with icons -->
<div class="btn-group">
    <button class="btn btn-outline-primary">
        <?= $this->Icon->render('list', ['set' => 'bs']) ?>
    </button>
    <button class="btn btn-outline-primary">
        <?= $this->Icon->render('grid', ['set' => 'bs']) ?>
    </button>
</div>

Common Icon Names

Icon Name Use Case
🏠 house Home, dashboard
list Menu, sidebar toggle
🔍 search Search functionality
📋 list-check Task list, checklist
⚙️ gear Settings
? question-circle Help, information
check Success, confirmation
x Close, cancel, delete
arrow-left Back, previous
arrow-right Next, forward
download Download, save
upload Upload, import
🔗 link Link, URL
🖨 printer Print

Status and Alerts

Icon Name Use Case
info-circle Information
exclamation-triangle Warning, caution
check-circle Success
x-circle Error, failure
pause-circle Paused status

People and Accounts

Icon Name Use Case
👤 person User, profile
👥 people Group, team
💼 briefcase Business, role
👑 crown Officer, authority
✏️ pencil Edit, modify

Data and Files

Icon Name Use Case
📄 file-text Document, text file
📊 graph-up Chart, graph, analytics
🗂 folder Folder, directory
📌 pin Pin, location
🏷 tag Tag, label, category
🔖 bookmark Bookmark, save

Communication

Icon Name Use Case
envelope Email, message
📞 telephone Phone, call
💬 chat Chat, comment
📢 megaphone Announce, broadcast

Calendar and Time

Icon Name Use Case
📅 calendar Date, calendar
🕐 clock Time, duration
stopwatch Timer, measurement
📆 calendar-event Event, appointment

Misc

Icon Name Use Case
star Favorite, rating
🔒 lock Secure, locked
🔑 key Password, access
🔄 arrow-clockwise Refresh, reload
+ plus Add, create
- dash Remove, subtract

See Bootstrap Icons official gallery for complete icon list.

Icon Styling

CSS Size Classes

Predefined size classes (optional):

.icon-sm { font-size: 0.875rem; }  /* 14px */
.icon-md { font-size: 1rem; }      /* 16px (default) */
.icon-lg { font-size: 1.5rem; }    /* 24px */
.icon-xl { font-size: 2rem; }      /* 32px */

Custom CSS

Add custom styles:

/* Size icon via em (scales with text) */
.icon-large {
    width: 2em;
    height: 2em;
}

/* Custom color */
.icon-danger {
    color: #dc3545;
}

/* Animation */
.icon-spin {
    animation: spin 1s linear infinite;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

Advanced Usage

Icons in Tables

<!-- In table cells -->
<tr>
    <td>
        <span title="Active">
            <?= $this->Icon->render('check-circle', ['set' => 'bs', 'class' => 'text-success']) ?>
        </span>
    </td>
    <td>John Smith</td>
    <td>
        <button class="btn btn-sm btn-outline-primary">
            <?= $this->Icon->render('pencil', ['set' => 'bs']) ?>
        </button>
        <button class="btn btn-sm btn-outline-danger">
            <?= $this->Icon->render('trash', ['set' => 'bs']) ?>
        </button>
    </td>
</tr>

Icons in Badges

<!-- Status badges with icons -->
<span class="badge bg-success">
    <?= $this->Icon->render('check', ['set' => 'bs', 'class' => 'me-1']) ?>
    Active
</span>

<span class="badge bg-warning">
    <?= $this->Icon->render('exclamation', ['set' => 'bs', 'class' => 'me-1']) ?>
    Pending
</span>

Icons in Lists

<!-- List items with icons -->
<ul class="list-unstyled">
    <li class="mb-2">
        <?= $this->Icon->render('check', ['set' => 'bs', 'class' => 'text-success me-2']) ?>
        Completed task
    </li>
    <li class="mb-2">
        <?= $this->Icon->render('exclamation', ['set' => 'bs', 'class' => 'text-warning me-2']) ?>
        Pending review
    </li>
</ul>

Icons in Forms

<!-- Input group with icon -->
<div class="input-group">
    <span class="input-group-text">
        <?= $this->Icon->render('search', ['set' => 'bs']) ?>
    </span>
    <input type="text" class="form-control" placeholder="Search...">
</div>

<!-- Icon label -->
<label>
    <?= $this->Icon->render('person', ['set' => 'bs', 'class' => 'me-2']) ?>
    Member Name
</label>

Dynamic Icons from Data

<?php
// Map status to icon
$statusIcons = [
    'active' => 'check-circle',
    'inactive' => 'x-circle',
    'pending' => 'question-circle',
];

$statusColors = [
    'active' => 'success',
    'inactive' => 'secondary',
    'pending' => 'warning',
];

foreach ($members as $member) {
    $icon = $statusIcons[$member->status] ?? 'circle';
    $color = $statusColors[$member->status] ?? 'secondary';
    ?>
    <tr>
        <td>
            <?= $this->Icon->render($icon, [
                'set' => 'bs',
                'class' => "text-{$color}"
            ]) ?>
        </td>
        <td><?= h($member->name) ?></td>
    </tr>
    <?php
}
?>

Performance Considerations

Inline SVG

Icons are rendered as inline SVG (embedded HTML):

Advantages:

Disadvantages:

Caching

Icon metadata is cached by CakePHP’s metadata cache. Clear if adding new icons:

bin/cake cache clear_all

Optimization Tips

  1. Use appropriate sizes: Don’t render oversized icons, scale with CSS
  2. Reuse icon names: Consistent naming makes caching effective
  3. Combine with other optimization: Use alongside asset minification
  4. Monitor bundle size: Track HTML size with many icons

Troubleshooting

Icon Not Displaying

  1. Verify icon name: Check spelling against Bootstrap Icons gallery
  2. Check path: Ensure webroot/assets/bootstrap-icons/ exists
  3. Clear cache: Run bin/cake cache clear_all
  4. Check JSON file: Verify bootstrap-icons.json is present and valid

Icon Showing as Missing

  1. Check JSON path: Verify path in config/app.php is correct
  2. File permissions: Ensure JSON file is readable
  3. Icon not in set: Icon name may not be in Bootstrap Icons 1.11.3
  4. Browser console: Check for JavaScript errors

Styling Not Applying

  1. CSS specificity: Ensure custom styles have sufficient specificity
  2. Class names: Verify Bootstrap classes are spelled correctly
  3. Bootstrap imported: Ensure Bootstrap CSS is loaded in assets/css/app.css
  4. Cache: Clear browser cache (Ctrl+F5)

Color Not Changing

Icons inherit currentColor from parent. Ensure color is set on parent or icon:

<!-- Correct: Color on parent -->
<span class="text-primary">
    <?= $this->Icon->render('star', ['set' => 'bs']) ?>
</span>

<!-- Also correct: Color via class -->
<?= $this->Icon->render('star', [
    'set' => 'bs',
    'class' => 'text-primary'
]) ?>

See Also