Support Log in

9. Building a Custom Language Switcher

Developer Guide
Prefer video? Watch the Lang Forge tutorials 9 short guides covering every feature Watch

If the built-in styles do not fit your design, build a completely custom switcher using the helper functions.

php
<?php
// components/language-switcher.php
$languages = lf_get_languages();
$current   = lf_get_current_language();
$core      = LF_Core::instance();

if (count($languages) <= 1) return;
?>

<div class="my-custom-switcher" data-current="<?php echo esc_attr($current); ?>">
    <button class="switcher-toggle" aria-expanded="false" aria-haspopup="true">
        <span class="current-flag">
            <img src="<?php echo esc_url(plugins_url('langforge/assets/flags/' . $languages[$current]['flag'] . '.svg')); ?>"
                 alt="" width="20" height="14">
        </span>
        <span class="current-name"><?php echo esc_html($languages[$current]['native_name']); ?></span>
        <svg class="chevron" width="12" height="12" viewBox="0 0 12 12">
            <path d="M3 5l3 3 3-3" stroke="currentColor" fill="none" stroke-width="1.5"/>
        </svg>
    </button>

    <ul class="switcher-menu" role="menu" hidden>
        <?php foreach ($languages as $code => $lang) : ?>
            <?php if ($code === $current) continue; ?>
            <li role="menuitem">
                <a href="<?php echo esc_url($core->get_language_url($code)); ?>">
                    <img src="<?php echo esc_url(plugins_url('langforge/assets/flags/' . $lang['flag'] . '.svg')); ?>"
                         alt="" width="20" height="14">
                    <span><?php echo esc_html($lang['native_name']); ?></span>
                </a>
            </li>
        <?php endforeach; ?>
    </ul>
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
    const switcher = document.querySelector('.my-custom-switcher');
    const toggle = switcher.querySelector('.switcher-toggle');
    const menu = switcher.querySelector('.switcher-menu');

    toggle.addEventListener('click', function() {
        const expanded = toggle.getAttribute('aria-expanded') === 'true';
        toggle.setAttribute('aria-expanded', !expanded);
        menu.hidden = expanded;
    });

    document.addEventListener('click', function(e) {
        if (!switcher.contains(e.target)) {
            toggle.setAttribute('aria-expanded', 'false');
            menu.hidden = true;
        }
    });
});
</script>
Example: Horizontal flags-only bar for a minimal header
css
.lf-language-switcher.lf-flags {
    display: flex;
    gap: 8px;
    align-items: center;
}

.lf-language-switcher.lf-flags .wpml-ls-item {
    list-style: none;
}

.lf-language-switcher.lf-flags .wpml-ls-link {
    display: block;
    opacity: 0.6;
    transition: opacity 0.2s, transform 0.2s;
}

.lf-language-switcher.lf-flags .wpml-ls-link:hover {
    opacity: 1;
    transform: scale(1.15);
}

.lf-language-switcher.lf-flags .wpml-ls-current-language .wpml-ls-link {
    opacity: 1;
}

.lf-language-switcher.lf-flags .wpml-ls-flag {
    width: 28px;
    height: 20px;
    border-radius: 3px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
Example: AJAX-powered switcher that preserves scroll position
php
<?php
// A switcher that uses JavaScript to switch language without full page reload
// when the translation exists. Falls back to standard link if not.
?>
<div class="ajax-lang-switcher">
    <?php
    $languages = lf_get_languages();
    $current = lf_get_current_language();
    $core = LF_Core::instance();

    foreach ($languages as $code => $lang) :
        $active = ($code === $current) ? ' active' : '';
        $url = esc_url($core->get_language_url($code));
    ?>
        <a href="<?php echo $url; ?>"
           class="lang-btn<?php echo $active; ?>"
           data-lang="<?php echo esc_attr($code); ?>">
            <?php echo esc_html($lang['native_name']); ?>
        </a>
    <?php endforeach; ?>
</div>

<script>
document.querySelectorAll('.ajax-lang-switcher .lang-btn').forEach(function(btn) {
    btn.addEventListener('click', function(e) {
        // Store scroll position before navigation
        sessionStorage.setItem('lf_scroll_y', window.scrollY);
    });
});

// Restore scroll position after page load
document.addEventListener('DOMContentLoaded', function() {
    var scrollY = sessionStorage.getItem('lf_scroll_y');
    if (scrollY) {
        window.scrollTo(0, parseInt(scrollY, 10));
        sessionStorage.removeItem('lf_scroll_y');
    }
});
</script>

Forge AI Assistant Online

Hi! I'm the Lang Forge AI assistant. Ask me anything about the plugin — setup, features, troubleshooting, or development.

Just now
Powered by Forge AI · Browse docs