Skip to main content
Voir en Markdown

Langues

Prise en charge multilingue avec clés de traduction, détection de la langue du navigateur et routage automatique par URL (/en/..., /fr/...). Référencez les traductions dans les pages avec le préfixe $t:.

Définir les langues

Définissez une langue par défaut et listez les langues prises en charge avec code, locale, libellé et direction du texte.

Propriété Description
default Code ISO 639-1 de la langue par défaut (par ex. "en"). Utilisé quand aucune langue n'est détectée.
supported Tableau d'objets d'entrée de langue. Chacun définit une langue prise en charge.
fallback Code de langue de secours (2 lettres). Utilisé quand une clé de traduction est manquante dans la langue active.
detectBrowser Booléen. Lorsque true, détecte automatiquement la langue du navigateur de l'utilisateur lors de la première visite.
persistSelection Booléen. Lorsque true, mémorise le choix de langue de l'utilisateur entre les sessions.
app.yaml
languages:
  default: en
  supported:
    - code: en
      locale: en-US
      label: English
      direction: ltr
    - code: fr
      locale: fr-FR
      label: 'Français'
      direction: ltr
    - code: ar
      locale: ar-SA
      label: 'العربية'
      direction: rtl

URL sans segment de langue

Certaines pages doivent être écrites par locale — une zone de documentation qui lie content/docs/en et content/docs/fr ne peut pas être une page unique — si bien que leur path porte un segment explicite : /en/docs, /fr/docs. Plus rien ne répond alors au /docs nu, et un lien, un favori ou un partage de cette URL tombait autrefois sur un 404.

Ce n'est plus le cas. Un chemin sans préfixe qui ne se résout sur aucune page, mais se résoudrait une fois préfixé, reçoit un 302 vers /{lang}{chemin} :

Requête Réponse
/docs 302/en/docs (ou /fr/docs — voir ci-dessous)
/docs/ 301/docs, puis 302/en/docs
/manifesto 200 — une page indépendante de la locale se résout sur place, sans redirection
/en/docs 200 — un préfixe explicite n'est jamais préfixé une seconde fois
/nope 404 — il n'y a rien vers quoi rediriger

Ce comportement est toujours actif. Aucune option de schéma ne le pilote : le repli ne se déclenche que là où un 404 surviendrait et où la page préfixée existe, une combinaison qui n'est jamais intentionnelle.

La langue est négociée, pas figée. C'est la langue détectée du navigateur lorsque detectBrowser vaut true et que l'en-tête Accept-Language correspond à un code configuré, et languages.default sinon — exactement la règle qu'utilise déjà la redirection de la racine /.

302, et non 301 — et cela compte. La cible dépend d'un en-tête de requête : le lien n'est donc pas permanent. Un 301 est mis en cache par les navigateurs et les intermédiaires, ce qui figerait pour toujours la première locale vue par ce visiteur. Sovrium trace déjà exactement cette ligne : /en/en/ est un 301 (déterministe, indépendant des en-têtes) tandis que //fr/ est un 302 (négocié).

Pour la même raison, chaque réponse négociée déclare Vary: Accept-Language — ce 302, ainsi que les deux branches de la racine : son 302 vers /{lang}/ et le 200 qu'elle sert dans la langue par défaut. Sans cela, un cache partagé stocke la réponse d'un visiteur sous l'URL nue et la sert au visiteur suivant, dont la propre négociation n'a alors jamais lieu.

La cible doit se résoudre. /nope reste un 404 net et n'est jamais envoyé vers /en/nope. Une redirection vers un 404 gaspille le saut, échoue quand même et conduit un robot d'indexation dans une impasse.

La cible doit aussi être lisible. La redirection n'est émise que vers une page qu'un visiteur anonyme peut ouvrir. Si /en/private est protégée par un rôle, /private répond 404 — indiscernable d'un chemin qui n'aurait jamais été déclaré, car rediriger révélerait l'existence de la page alors que /en/private s'emploie précisément à la masquer. Voir Routage et chemins.

La chaîne de requête entrante est préservée, et /api/, /assets/, /_admin/ et /.well-known/ ne sont jamais touchés.

Propriétés d'entrée de langue

Chaque entrée du tableau supported décrit une langue avec ces propriétés.

Propriété Description
code Code de langue ISO 639-1 (par ex. "en", "fr", "ar"). Utilisé dans le routage par URL (/en/, /fr/).
locale Identifiant de locale complet (par ex. "en-US", "fr-FR", "ar-SA"). Utilisé pour le formatage des nombres et dates.
label Nom lisible de la langue affiché dans les sélecteurs de langue (par ex. "English", "Français").
direction Direction du texte : "ltr" (gauche à droite) pour la plupart des langues, "rtl" (droite à gauche) pour l'arabe, l'hébreu, etc.
flag Emoji drapeau ou chemin d'icône affiché dans les sélecteurs de langue.

Clés de traduction

Définissez des paires clé-valeur pour chaque langue. Les clés utilisent la notation pointée pour l'organisation.

app.yaml
languages:
  translations:
    en:
      hero.title: 'Welcome to My App'
      hero.description: 'Build faster with Sovrium'
      nav.home: 'Home'
      nav.about: 'About'
    fr:
      hero.title: 'Bienvenue sur Mon App'
      hero.description: 'Construisez plus vite avec Sovrium'
      nav.home: 'Accueil'
      nav.about: 'À propos'

Utiliser les traductions

Référencez les traductions dans tout contenu ou valeur de propriété avec le préfixe $t:.

app.yaml
# Reference translations with $t: prefix
pages:
  - name: home
    path: /
    components:
      - type: container
        children:
          - type: text
            element: h1
            content: 'hero.title'
          - type: text
            content: 'hero.description'

Version anglaise de l'application

Version française de l'application

Ajouter une nouvelle langue

Suivez ces étapes pour ajouter une nouvelle langue à votre application.

  1. Ajouter l'entrée de langue — Ajoutez un nouvel élément au tableau supported avec code, locale, label et direction.
  2. Ajouter les traductions — Créez une nouvelle section translations pour le code de langue avec toutes les clés nécessaires.
  3. Tester la langue — Visitez /[lang-code]/ dans votre navigateur pour vérifier que la nouvelle langue s'affiche correctement.

Dernière mise à jour 28 août 2026

Cette documentation a été rédigée avec de l'IA : des erreurs ou du contenu obsolète sont donc possibles. Sovrium est en bêta. Les contributions et corrections sont les bienvenues.

Construit avec Sovrium