Component

Language Switcher

Language selector dropdown with country flags, search functionality, grouped languages, and RTL support.

  • Component
  • Tailwind
  • HTML
  • MIT

Preview

Live component

Interactive preview
Open preview
9:41 100%
devsnips.dev/library/tailwind/components/dropdowns/language-switcher/
fluid · no fixed width 100%
No dependencies Production-ready

Install

Add to your project

terminal
npx devsnips add Tailwind/Components/Dropdowns/language-switcher
registry path: Tailwind/Components/Dropdowns/language-switcher

Source

Implementation

code.html
<!-- Language Switcher -->
<div class="relative inline-block">
  <button
    id="lang-button"
    class="flex items-center gap-2 px-3 py-2 text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"
    onclick="toggleDropdown('lang-menu')"
  >
    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129"></path>
    </svg>
    <span id="current-lang">English</span>
    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
    </svg>
  </button>

  <div
    id="lang-menu"
    class="hidden absolute left-0 z-20 mt-2 w-64 bg-white rounded-xl shadow-xl border border-gray-200 overflow-hidden"
  >
    <div class="py-2">
      <!-- Search -->
      <div class="px-3 pb-3">
        <div class="relative">
          <svg class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
          </svg>
          <input
            type="text"
            placeholder="Search languages..."
            class="w-full pl-9 pr-4 py-2 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
            oninput="filterLanguages(this.value)"
          />
        </div>
      </div>

      <!-- Popular Languages -->
      <div class="px-3 pb-2">
        <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider">Popular</p>
      </div>

      <button
        class="lang-option w-full flex items-center justify-between px-4 py-2.5 text-sm text-gray-700 hover:bg-blue-50 transition-colors"
        data-lang="English"
        onclick="selectLanguage(this)"
      >
        <div class="flex items-center gap-3">
          <span class="text-xl">🇺🇸</span>
          <span>English</span>
        </div>
        <svg class="w-4 h-4 text-blue-600 hidden check-icon" fill="currentColor" viewBox="0 0 20 20">
          <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
        </svg>
      </button>

      <button
        class="lang-option w-full flex items-center justify-between px-4 py-2.5 text-sm text-gray-700 hover:bg-blue-50 transition-colors"
        data-lang="Spanish"
        onclick="selectLanguage(this)"
      >
        <div class="flex items-center gap-3">
          <span class="text-xl">🇪🇸</span>
          <span>Español</span>
        </div>
        <svg class="w-4 h-4 text-blue-600 hidden check-icon" fill="currentColor" viewBox="0 0 20 20">
          <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
        </svg>
      </button>

      <button
        class="lang-option w-full flex items-center justify-between px-4 py-2.5 text-sm text-gray-700 hover:bg-blue-50 transition-colors"
        data-lang="French"
        onclick="selectLanguage(this)"
      >
        <div class="flex items-center gap-3">
          <span class="text-xl">🇫🇷</span>
          <span>Français</span>
        </div>
        <svg class="w-4 h-4 text-blue-600 hidden check-icon" fill="currentColor" viewBox="0 0 20 20">
          <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
        </svg>
      </button>

      <button
        class="lang-option w-full flex items-center justify-between px-4 py-2.5 text-sm text-gray-700 hover:bg-blue-50 transition-colors"
        data-lang="German"
        onclick="selectLanguage(this)"
      >
        <div class="flex items-center gap-3">
          <span class="text-xl">🇩🇪</span>
          <span>Deutsch</span>
        </div>
        <svg class="w-4 h-4 text-blue-600 hidden check-icon" fill="currentColor" viewBox="0 0 20 20">
          <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
        </svg>
      </button>

      <!-- Divider -->
      <div class="border-t border-gray-100 my-2"></div>

      <!-- More Languages -->
      <div class="px-3 pb-2">
        <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider">More Languages</p>
      </div>

      <button
        class="lang-option w-full flex items-center justify-between px-4 py-2.5 text-sm text-gray-700 hover:bg-blue-50 transition-colors"
        data-lang="Portuguese"
        onclick="selectLanguage(this)"
      >
        <div class="flex items-center gap-3">
          <span class="text-xl">🇧🇷</span>
          <span>Português</span>
        </div>
        <svg class="w-4 h-4 text-blue-600 hidden check-icon" fill="currentColor" viewBox="0 0 20 20">
          <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
        </svg>
      </button>

      <button
        class="lang-option w-full flex items-center justify-between px-4 py-2.5 text-sm text-gray-700 hover:bg-blue-50 transition-colors"
        data-lang="Japanese"
        onclick="selectLanguage(this)"
      >
        <div class="flex items-center gap-3">
          <span class="text-xl">🇯🇵</span>
          <span>日本語</span>
        </div>
        <svg class="w-4 h-4 text-blue-600 hidden check-icon" fill="currentColor" viewBox="0 0 20 20">
          <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
        </svg>
      </button>

      <button
        class="lang-option w-full flex items-center justify-between px-4 py-2.5 text-sm text-gray-700 hover:bg-blue-50 transition-colors"
        data-lang="Chinese"
        onclick="selectLanguage(this)"
      >
        <div class="flex items-center gap-3">
          <span class="text-xl">🇨🇳</span>
          <span>中文</span>
        </div>
        <svg class="w-4 h-4 text-blue-600 hidden check-icon" fill="currentColor" viewBox="0 0 20 20">
          <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
        </svg>
      </button>

      <button
        class="lang-option w-full flex items-center justify-between px-4 py-2.5 text-sm text-gray-700 hover:bg-blue-50 transition-colors"
        data-lang="Korean"
        onclick="selectLanguage(this)"
      >
        <div class="flex items-center gap-3">
          <span class="text-xl">🇰🇷</span>
          <span>한국어</span>
        </div>
        <svg class="w-4 h-4 text-blue-600 hidden check-icon" fill="currentColor" viewBox="0 0 20 20">
          <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
        </svg>
      </button>

      <button
        class="lang-option w-full flex items-center justify-between px-4 py-2.5 text-sm text-gray-700 hover:bg-blue-50 transition-colors"
        data-lang="Arabic"
        onclick="selectLanguage(this)"
      >
        <div class="flex items-center gap-3">
          <span class="text-xl">🇸🇦</span>
          <span>العربية</span>
        </div>
        <svg class="w-4 h-4 text-blue-600 hidden check-icon" fill="currentColor" viewBox="0 0 20 20">
          <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
        </svg>
      </button>
    </div>
  </div>
</div>

<script>
  function toggleDropdown(id) {
    document.getElementById(id).classList.toggle('hidden');
  }

  function selectLanguage(element) {
    const lang = element.getAttribute('data-lang');
    document.getElementById('current-lang').textContent = lang;
    
    document.querySelectorAll('.lang-option').forEach(opt => {
      opt.classList.remove('bg-blue-50');
      opt.querySelector('.check-icon').classList.add('hidden');
    });
    
    element.classList.add('bg-blue-50');
    element.querySelector('.check-icon').classList.remove('hidden');
    
    toggleDropdown('lang-menu');
  }

  function filterLanguages(query) {
    const normalizedQuery = query.toLowerCase();
    document.querySelectorAll('.lang-option').forEach(option => {
      const lang = option.getAttribute('data-lang').toLowerCase();
      if (lang.includes(normalizedQuery)) {
        option.classList.remove('hidden');
      } else {
        option.classList.add('hidden');
      }
    });
  }

  document.addEventListener('click', function(event) {
    const container = document.querySelector('.relative.inline-block');
    if (!container.contains(event.target)) {
      document.getElementById('lang-menu').classList.add('hidden');
    }
  });
</script>
217 lines UTF-8 · LF · Spaces: 2

AI-ready

Available to your agent.

This component is reachable through the DevSnips CLI, MCP server and Skills integrations — one registry, one resource path.

Resource path

devsnips://components/dropdowns/language-switcher

Continue browsing

View all