Component
Language Switcher
Language selector dropdown with country flags, search functionality, grouped languages, and RTL support.
- Component
- Tailwind
- HTML
- MIT
Preview
Live component
9:41 100%
devsnips.site/library/tailwind/components/dropdowns/language-switcher/ fluid · no fixed width 100%
Install
Add to your project
npx devsnips add Tailwind/Components/Dropdowns/language-switcher Tailwind/Components/Dropdowns/language-switcher <!-- 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> # Language Switcher
Language selection dropdown.
## Preview
Open `preview.html` for a standalone demonstration.
## Features
- Locale options
- Flag / label treatments as present
## Usage
```bash
npx devsnips add Tailwind/Components/Dropdowns/language-switcher
```
Copy from `code.html`.
## Customization
- Option list and trigger styles
## Accessibility
- Expose the current language accessibly
## Dependencies
- Tailwind CSS; JS as present
## File Structure
- `code.html` · `preview.html` · `metadata.json` · `README.md` 217 lines UTF-8 · LF · Spaces: 2
DevSnips AI ready Claude · Cursor · Windsurf
Agent skill & Model Context Protocol
Pass this component straight into your AI workflow. DevSnips exposes each resource as a structured, addressable registry entry, so your agent installs the real files instead of approximating them.
devsnips://components/dropdowns/language-switcher I want to use this DevSnips resource in production: Page: https://devsnips.site/library/tailwind/components/dropdowns/language-switcher/ Install: npx devsnips add Tailwind/Components/Dropdowns/language-switcher This is the Language Switcher — Language selector dropdown with country flags, search functionality, grouped languages, and RTL support. Use this DevSnips resource as the starting point for my project. Adapt it to my project's stack and conventions, fix any issues, and make it production-ready while preserving its intended design and behavior.
Paste into ChatGPT, Claude or your agent — it already carries the page URL and the exact install path.
Resource URI
devsnips://components/dropdowns/language-switcher