Multilanguage Setup

The blökkli starterkit is built with multilingual support in mind. The frontend and the backend are prepared to handle multiple languages. We use four pillars to achieve full multilanguage integration in our headless setup.

1. Drupal Content Translation

The first and most important part ist the standard Drupal content translation. Drupal provides a powerful translation system that allows us to translate all content entities, such as nodes, paragraphs, and taxonomy terms. The content translation is done via Drupal backend or in blökkli via the frontend.

We leverage the GraphQL routeQuery to fetch automatically the correct translations based on the current language. drupal_translation.png

2. Nuxt Language Negotiation

The Nuxt Language Negotiation provides basic multi-language support for our Nuxt 3 application. It's minimal by design and tries to do only a few things:

Features

  • SSR language negotiation/detection based on path prefix, Accept-Language or custom (e.g. via API).
  • Single source of truth for "current language" state
  • Multi-language routes via languageMapping meta property
nuxt.config.ts
export default defineNuxtConfig({
    modules: ['nuxt-language-negotiation'],
    
    languageNegotiation: {
        // Define the available languages.
        availableLanguages: ['en', 'de', 'fr', 'it'],
        // The default language has no prefix in the URL.
        defaultLanguageNoPrefix: false,
        
        // We use two negotiators: Path prefix takes precedence. In cases where no
        // path prefix is available, we fallback to Accept-Language headers.
        negotiators: ['pathPrefix', 'acceptLanguage'],
    
        // Write debug messages to the console on client and server.
        debug: true,
    },
})

3. Nuxt Easy Texts

This module provides a string extractor similar to the famous Drupal t function.

It provides a $texts() function that can be used in Vue components to translate strings. The module automatically collects translatable texts with a rollup plugin and loads their translations at runtime (for example from an API endpoint). The compiled build will only contain the keys and no text values.

components/Carousel.vue
<nav class="carousel__navigation-container--inner">
  <button :aria-label="$texts('slides.prev', 'Previous')" />
  <button :aria-label="$texts('slides.next', 'Next')" />
</nav>
queries/translations.graphql
# This file is automatically generated by the nuxt-easy-texts module.
# Any manual changes will be overwritten.

fragment easyTexts on TextsLoader {
  home: getText(key: "home", default: "Home")
  slides__next: getText(key: "next", context: "slides", default: "Previous")
  slides__prev: getText(key: "prev", context: "slides", default: "Next")
}

4. Drupal Texts module

This drupal module is the backend counterpart to the Nuxt Easy Texts module. It provides a Drupal UI to manage key-based translations. It allows you to manage your frontend translations within Drupal with ease. The module offers an improved UI to manage translations in the Drupal backend.

It supports pluralization (singular / plural) and placeholders, like the normal t() function. The module comes with optional GraphQL support to fetch the translations in a decoupled environment. drupal_texts.png