X Menu sluiten

A language switcher example

Published on Saturday, February 09, 2019

Living in Belgium, most of the sites I make have to be at least 2 languages: Dutch and French. Often there's also English and German. So I use a language navigation snippet in just about every site.

This snippet makes a few assumptions:

- You group the sites you want to link to in the same group
- You have an array of site urls in your general config

{% set currentLanguage = currentSite.language %}

{% set group = craft.app.getSites().getGroupById(currentSite.groupId) %}

{% for site in group.getSites() %}

    {% if entry is defined %}
        {% set localeEntry = craft.entries.id(entry.id).siteId(site.id).one() %}
        {% if localeEntry.siteId is defined and localeEntry.siteId != currentSite.id %}
            {% set locale = localeEntry.site.language|split('-')  %}

                <a href="{{ localeEntry.url }}" class="nav__link">{{ locale[0]|upper }}</a>

        {% else %}
            {% if localeEntry %}
                {% set locale = localeEntry.site.language|split('-')  %}

                    <a href="{{ craft.app.config.general.siteUrl[localeEntry.site.handle] }}" class="nav__link">{{ locale[0]|upper }}</a>

            {% endif %}
        {% endif %}
    {% endif %}

{% endfor %}

Let's break it down.

First off, we get all sites in the group, based of the group of the current site (this follows the practice where translated sites are in the same group, and the groups themselves are the actual different sites). Then we can loop through those sites.

{% set currentLanguage = currentSite.language %}
{% set group = craft.app.getSites().getGroupById(currentSite.groupId) %}

{% for site in group.getSites() %}
{% endfor %}

Then we check if we have an entry that can be used to get a translation for and to link to. This snippet can easily be adapted to also work with products or categories.

If you're on a route your created yourself and you don't have an entry, you'll have to add a condition for that.

We're still inside our Sites loop we first we add a condition to check that the site we're on in the loop is not our currentSite and then we get the link for the entry in that other site.

{% set localeEntry = craft.entries.id(entry.id).siteId(site.id).one() %}
{% if localeEntry.siteId is defined and localeEntry.siteId != currentSite.id %}
    {% set locale = localeEntry.site.language|split('-')  %}

        <a href="{{ localeEntry.url }}" class="nav__link">{{ locale[0]|upper }}</a>

{% else %}
    {% if localeEntry %}
        {% set locale = localeEntry.site.language|split('-')  %}

            <a href="{{ craft.app.config.general.siteUrl[localeEntry.site.handle] }}" class="nav__link">{{ locale[0]|upper }}</a>

    {% endif %}
{% endif %}

If we're on the current site, there are a couple of options. We could link the language navigation link to:

- the current page (so linking to the page you're on at the moment)
- link to the homepage for that language/site (that's what the example does right now
- not link it at all

We usually link it to the siteUrl for the current site.

Are you doing this in a totally different way or see something that can be improved here? Feel free to add your comment below!