Snippets Chat

Bootstrap 5 Chat Room Layout with Conversation List

A two-pane chat room with a searchable conversation list, message bubbles with timestamps, an options menu and a working composer.

Bootstrap 5 Bootstrap 6 No jQuery Sep 2019 20.8K views

<section class="wdw-stage">
  <div class="container" style="max-width:1040px">
    <div class="wdw-card cr overflow-hidden">
      <aside class="cr-side">
        <div class="p-3 pb-2">
          <h1 class="h5 wdw-heading mb-3">Messages</h1>
          <label class="visually-hidden" for="crSearch">Search conversations</label>
          <input type="search" id="crSearch" class="form-control rounded-pill" placeholder="Search conversations">
        </div>
        <div class="cr-list px-2 pb-2" id="crList">
<button type="button" class="cr-conv active" data-name="Maya Chen" data-img="5" aria-pressed="true"><span class="cr-av"><img src="https://i.pravatar.cc/80?img=5" width="44" height="44" class="rounded-circle" alt=""><span class="cr-dot"></span></span><span class="cr-conv-main"><span class="d-flex justify-content-between gap-2"><strong class="text-truncate">Maya Chen</strong><small class="wdw-muted flex-shrink-0">09:45</small></span><span class="d-flex justify-content-between gap-2"><span class="wdw-muted small text-truncate">Sounds good, see you then!</span><span class="badge rounded-pill text-bg-primary">2</span></span></span></button>
<button type="button" class="cr-conv" data-name="Design Team" data-img="" data-group="1" aria-pressed="false"><span class="cr-av"><span class="cr-group rounded-circle" aria-hidden="true"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="8" r="3.2"/><path d="M3 20c0-3.3 2.7-6 6-6s6 2.7 6 6"/><path d="M16 5.2a3.2 3.2 0 0 1 0 5.6M18 14.4c2 .8 3.5 2.8 3.5 5.6"/></svg></span></span><span class="cr-conv-main"><span class="d-flex justify-content-between gap-2"><strong class="text-truncate">Design Team</strong><small class="wdw-muted flex-shrink-0">09:12</small></span><span class="d-flex justify-content-between gap-2"><span class="wdw-muted small text-truncate">Leo (member): Updated the mockups</span></span></span></button>
<button type="button" class="cr-conv" data-name="Jack Sparrow" data-img="15" aria-pressed="false"><span class="cr-av"><img src="https://i.pravatar.cc/80?img=15" width="44" height="44" class="rounded-circle" alt=""></span><span class="cr-conv-main"><span class="d-flex justify-content-between gap-2"><strong class="text-truncate">Jack Sparrow</strong><small class="wdw-muted flex-shrink-0">Yesterday</small></span><span class="d-flex justify-content-between gap-2"><span class="wdw-muted small text-truncate">Can you send the file?</span><span class="badge rounded-pill text-bg-primary">3</span></span></span></button>
<button type="button" class="cr-conv" data-name="Priya Nair" data-img="47" aria-pressed="false"><span class="cr-av"><img src="https://i.pravatar.cc/80?img=47" width="44" height="44" class="rounded-circle" alt=""></span><span class="cr-conv-main"><span class="d-flex justify-content-between gap-2"><strong class="text-truncate">Priya Nair</strong><small class="wdw-muted flex-shrink-0">Yesterday</small></span><span class="d-flex justify-content-between gap-2"><span class="wdw-muted small text-truncate">Thanks a lot</span></span></span></button>
<button type="button" class="cr-conv" data-name="Tom Becker" data-img="8" aria-pressed="false"><span class="cr-av"><img src="https://i.pravatar.cc/80?img=8" width="44" height="44" class="rounded-circle" alt=""><span class="cr-dot"></span></span><span class="cr-conv-main"><span class="d-flex justify-content-between gap-2"><strong class="text-truncate">Tom Becker</strong><small class="wdw-muted flex-shrink-0">Mon</small></span><span class="d-flex justify-content-between gap-2"><span class="wdw-muted small text-truncate">Let's catch up soon</span></span></span></button>
        </div>
      </aside>
      <div class="cr-main">
        <header class="d-flex align-items-center gap-3 px-4 py-3 border-bottom">
          <span class="cr-av"><img id="crAvatar" src="https://i.pravatar.cc/80?img=5" width="44" height="44" class="rounded-circle" alt=""><span class="cr-group rounded-circle" id="crGroup" hidden aria-hidden="true"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="8" r="3.2"/><path d="M3 20c0-3.3 2.7-6 6-6s6 2.7 6 6"/><path d="M16 5.2a3.2 3.2 0 0 1 0 5.6M18 14.4c2 .8 3.5 2.8 3.5 5.6"/></svg></span><span class="cr-dot" id="crDot"></span></span>
          <div class="me-auto"><strong id="crName" class="d-block">Maya Chen</strong><small class="text-body-secondary d-inline-flex align-items-center gap-2" id="crStatus"><span class="cr-pip" aria-hidden="true"></span><span id="crStatusText">Online</span></small></div>
          <div class="dropdown">
            <button class="btn btn-sm rounded-pill px-3 cr-opt" type="button" data-bs-toggle="dropdown" aria-expanded="false">Options</button>
            <ul class="dropdown-menu dropdown-menu-end border-0"><li><button class="dropdown-item" type="button">Mute</button></li><li><button class="dropdown-item" type="button">Pin conversation</button></li><li><hr class="dropdown-divider"></li><li><button class="dropdown-item text-danger" type="button">Clear chat</button></li></ul>
          </div>
        </header>
        <div class="cr-thread px-4 py-4" id="crThread" aria-live="polite">
          <div class="cr-day">Today</div>
          <div class="cr-msg"><p>Hi! Did you get a chance to look at the new landing page draft?</p><time>09:38</time></div>
          <div class="cr-msg me"><p>Yes, it looks great. I left a few notes on the hero section.</p><time>09:40</time></div>
          <div class="cr-msg"><p>Perfect, I'll update it this afternoon. Free for a quick call at 3?</p><time>09:44</time></div>
          <div class="cr-msg me"><p>Sounds good, see you then!</p><time>09:45</time></div>
        </div>
        <form class="d-flex gap-2 p-3 border-top" id="crForm">
          <label class="visually-hidden" for="crInput">Message</label>
          <button type="button" class="btn cr-ico rounded-circle p-0" aria-label="Attach a file"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m21 11-8.6 8.6a5 5 0 0 1-7-7L14 4a3.4 3.4 0 0 1 5 5l-8.6 8.6a1.7 1.7 0 0 1-2.4-2.4L15 8"/></svg></button>
          <button type="button" class="btn cr-ico rounded-circle p-0 d-none d-sm-inline-flex" aria-label="Insert emoji"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M8.5 14.5a4.5 4.5 0 0 0 7 0M9 9.5h.01M15 9.5h.01"/></svg></button>
          <input type="text" id="crInput" class="form-control rounded-pill" placeholder="Write a message" autocomplete="off">
          <button type="submit" class="btn btn-primary rounded-pill px-4">Send</button>
        </form>
      </div>
    </div>
  </div>
</section>

Built on Bootstrap 6.0.0-alpha.1 (ES modules, no jQuery). Load Bootstrap through an import map and run the JavaScript as type="module" — the downloaded file is already set up that way. Alpha releases can still change class names.

Built on Bootstrap 5.3.8 with plain JavaScript — no jQuery. Supports light and dark mode via data-bs-theme.

Free to use in personal and commercial projects under the MIT license.