mirror of
https://github.com/mintlify/docs.git
synced 2026-09-14 13:35:46 +08:00
6a95003775
* Add warning about duplicating paths across locales Generated-By: mintlify-agent * Apply suggestion from @ethanpalm --------- Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com> Co-authored-by: Ethan Palm <56270045+ethanpalm@users.noreply.github.com>
793 lines
28 KiB
Plaintext
793 lines
28 KiB
Plaintext
---
|
||
title: "Comment configurer une documentation multilingue"
|
||
sidebarTitle: "Internationalisation"
|
||
description: "Configurez une documentation multilingue avec un routage par locale, un sélecteur de langue dans la navigation et du contenu traduit pour toucher un public mondial."
|
||
keywords: ["internationalisation", "i18n", "documentation multilingue", "traductions", "localisation", "sélecteur de langue"]
|
||
---
|
||
|
||
L’internationalisation (i18n) est le processus qui consiste à concevoir un logiciel ou du contenu pour fonctionner avec différentes langues et différents paramètres régionaux. Ce guide explique comment structurer les fichiers, configurer la navigation et maintenir les traductions efficacement afin que vous puissiez aider vos utilisateurs à accéder à votre documentation dans leur langue préférée et améliorer votre portée à l’international.
|
||
|
||
<div id="file-structure">
|
||
## Structure des fichiers
|
||
</div>
|
||
|
||
Organisez le contenu traduit dans des répertoires propres à chaque langue afin que votre documentation reste facile à maintenir et pour structurer votre navigation par langue.
|
||
|
||
Créez un répertoire séparé pour chaque langue en utilisant les [codes de langue ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). Placez les fichiers traduits dans ces répertoires en respectant la même structure que pour votre langue par défaut.
|
||
|
||
<Expandable title="codes de langue pris en charge">
|
||
* `ar` - arabe
|
||
* `ca` - catalan
|
||
* `cs` - tchèque
|
||
* `zh` ou `zh-Hans` - chinois (simplifié)
|
||
* `zh-Hant` - chinois (traditionnel)
|
||
* `de` - allemand
|
||
* `en` - anglais
|
||
* `es` - espagnol
|
||
* `fi` - finnois
|
||
* `fr` - français
|
||
* `fr-CA` - français (canadien)
|
||
* `he` - hébreu
|
||
* `hi` - hindi
|
||
* `hu` - hongrois
|
||
* `id` - indonésien
|
||
* `it` - italien
|
||
* `ja` - japonais
|
||
* `ko` - coréen
|
||
* `lv` - letton
|
||
* `nl` - néerlandais
|
||
* `no` - norvégien
|
||
* `pl` - polonais
|
||
* `pt` ou `pt-BR` - portugais
|
||
* `ro` - roumain
|
||
* `ru` - russe
|
||
* `sv` - suédois
|
||
* `tr` - turc
|
||
* `uk` - ukrainien
|
||
* `uz` - ouzbek
|
||
* `vi` - vietnamien
|
||
</Expandable>
|
||
|
||
```text Example file structure
|
||
docs/
|
||
├── index.mdx # anglais (par défaut)
|
||
├── quickstart.mdx
|
||
├── fr/
|
||
│ ├── index.mdx # français
|
||
│ ├── quickstart.mdx
|
||
├── es/
|
||
│ ├── index.mdx # espagnol
|
||
│ ├── quickstart.mdx
|
||
└── zh/
|
||
├── index.mdx # chinois
|
||
└── quickstart.mdx
|
||
```
|
||
|
||
<Tip>
|
||
Conservez les mêmes noms de fichiers et la même structure de répertoires dans toutes les langues. Cela facilite la maintenance des traductions et l’identification du contenu manquant.
|
||
</Tip>
|
||
|
||
|
||
<div id="configure-the-language-switcher">
|
||
## Configurer le sélecteur de langue
|
||
</div>
|
||
|
||
Pour ajouter un sélecteur de langue à votre documentation, configurez le tableau `languages` dans la propriété `navigation` de votre fichier `docs.json`.
|
||
|
||
```json docs.json
|
||
{
|
||
"navigation": {
|
||
"languages": [
|
||
{
|
||
"language": "en",
|
||
"groups": [
|
||
{
|
||
"group": "Premiers pas",
|
||
"pages": ["index", "quickstart"]
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"language": "es",
|
||
"groups": [
|
||
{
|
||
"group": "Comenzando",
|
||
"pages": ["es/index", "es/quickstart"]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
Chaque entrée de langue dans le tableau `languages` nécessite :
|
||
|
||
* `language` : code de langue ISO 639-1
|
||
* Une structure de navigation complète
|
||
* Les chemins d’accès aux fichiers traduits
|
||
|
||
La structure de navigation peut différer selon les langues pour s’adapter aux besoins de contenu propres à chacune.
|
||
|
||
<Warning>
|
||
N’utilisez pas le même chemin de page dans plusieurs locales. La duplication de chemins entre les locales entraîne un comportement indéfini. Chaque chemin de page ne doit apparaître que dans la navigation d’une seule langue.
|
||
</Warning>
|
||
|
||
<div id="set-default-language">
|
||
### Définir la langue par défaut
|
||
</div>
|
||
|
||
La première langue du tableau `languages` est automatiquement utilisée comme langue par défaut. Pour définir une autre langue comme langue par défaut, réorganisez le tableau ou ajoutez la propriété `default` :
|
||
|
||
```json docs.json
|
||
{
|
||
"navigation": {
|
||
"languages": [
|
||
{
|
||
"language": "es",
|
||
"groups": [...]
|
||
},
|
||
{
|
||
"language": "en",
|
||
"groups": [...]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
Vous pouvez également utiliser la propriété `default` pour modifier l’ordre :
|
||
|
||
```json docs.json
|
||
{
|
||
"navigation": {
|
||
"languages": [
|
||
{
|
||
"language": "en",
|
||
"groups": [...]
|
||
},
|
||
{
|
||
"language": "es",
|
||
"default": true,
|
||
"groups": [...]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
<div id="single-language-documentation">
|
||
### Documentation en une seule langue
|
||
</div>
|
||
|
||
Si vous ne souhaitez proposer qu’une seule langue sans sélecteur de langue, supprimez le champ `languages` de votre configuration de navigation. Définissez ensuite directement votre structure de navigation :
|
||
|
||
```json docs.json
|
||
{
|
||
"navigation": {
|
||
"tabs": [
|
||
{
|
||
"tab": "Documentation",
|
||
"groups": [
|
||
{
|
||
"group": "Premiers pas",
|
||
"pages": ["index", "quickstart"]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
Cela affiche votre documentation dans une seule langue, sans l’interface du sélecteur de langue.
|
||
|
||
<Tip>
|
||
Traduisez les libellés de navigation, comme les noms de groupes ou d’onglets, afin de les faire correspondre à la langue du contenu. Cela crée une expérience entièrement localisée pour vos utilisateurs.
|
||
</Tip>
|
||
|
||
|
||
<div id="global-navigation">
|
||
### Navigation globale
|
||
</div>
|
||
|
||
Pour ajouter des éléments de navigation globaux qui apparaissent dans toutes les langues, configurez l'objet `global` dans la propriété `navigation` de votre fichier `docs.json`.
|
||
|
||
```json docs.json
|
||
{
|
||
"navigation": {
|
||
"global": {
|
||
"anchors": [
|
||
{
|
||
"anchor": "Documentation",
|
||
"href": "https://example.com/docs"
|
||
},
|
||
{
|
||
"anchor": "Blog",
|
||
"href": "https://example.com/blog"
|
||
}
|
||
]
|
||
},
|
||
"languages": [
|
||
// Navigation spécifique à chaque langue
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
<div id="localized-footer-and-navbar">
|
||
### Pied de page et barre de navigation par langue
|
||
</div>
|
||
|
||
Personnalisez le pied de page et la barre de navigation pour chaque langue afin d'afficher du contenu traduit et des liens adaptés à chaque région.
|
||
|
||
Ajoutez les propriétés `footer` et `navbar` à chaque configuration de langue :
|
||
|
||
```json docs.json
|
||
{
|
||
"navigation": {
|
||
"languages": [
|
||
{
|
||
"language": "en",
|
||
"footer": {
|
||
"socials": {
|
||
"x": "https://x.com/mintlify"
|
||
},
|
||
"links": [
|
||
{
|
||
"header": "Resources",
|
||
"items": [
|
||
{ "label": "Documentation", "href": "/en/docs" },
|
||
{ "label": "Blog", "href": "https://mintlify.com/blog" }
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"navbar": {
|
||
"links": [
|
||
{ "label": "Docs", "href": "/en/docs" }
|
||
],
|
||
"primary": {
|
||
"type": "button",
|
||
"label": "Get Started",
|
||
"href": "/en/quickstart"
|
||
}
|
||
},
|
||
"groups": [
|
||
{
|
||
"group": "Getting started",
|
||
"pages": ["en/quickstart", "en/index"]
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"language": "es",
|
||
"footer": {
|
||
"socials": {
|
||
"x": "https://x.com/mintlify"
|
||
},
|
||
"links": [
|
||
{
|
||
"header": "Recursos",
|
||
"items": [
|
||
{ "label": "Documentación", "href": "/es/docs" },
|
||
{ "label": "Blog", "href": "https://mintlify.com/blog" }
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"navbar": {
|
||
"links": [
|
||
{ "label": "Documentación", "href": "/es/docs" }
|
||
],
|
||
"primary": {
|
||
"type": "button",
|
||
"label": "Comenzar",
|
||
"href": "/es/quickstart"
|
||
}
|
||
},
|
||
"groups": [
|
||
{
|
||
"group": "Comenzando",
|
||
"pages": ["es/quickstart", "es/index"]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
Le `footer` et la `navbar` propres à une langue remplacent les paramètres globaux pour cette langue. Si une langue ne définit pas ces propriétés, elle hérite de la configuration globale.
|
||
|
||
Vous pouvez également configurer une `banner` propre à une langue en suivant le même schéma.
|
||
|
||
|
||
<div id="maintain-translations">
|
||
## Conserver les traductions
|
||
</div>
|
||
|
||
Veillez à ce que vos traductions restent exactes et synchronisées avec votre contenu source.
|
||
|
||
<div id="translation-workflow">
|
||
### Processus de traduction
|
||
</div>
|
||
|
||
1. Mettez à jour le contenu source dans votre langue principale.
|
||
2. Identifiez le contenu modifié.
|
||
3. Traduisez le contenu modifié.
|
||
4. Relisez les traductions pour en vérifier l’exactitude.
|
||
5. Mettez à jour les fichiers traduits.
|
||
6. Vérifiez que la navigation et les liens fonctionnent.
|
||
|
||
<div id="automated-translations">
|
||
### Traductions automatisées
|
||
</div>
|
||
|
||
Pour des solutions de traduction automatique, [contactez l'équipe commerciale de Mintlify](mailto:gtm@mintlify.com).
|
||
|
||
<div id="external-translation-providers">
|
||
### Prestataires de traduction externes
|
||
</div>
|
||
|
||
Si vous travaillez avec vos propres prestataires de traduction ou traducteurs régionaux, vous pouvez intégrer leur processus à votre documentation Mintlify à l’aide de GitHub Actions ou d’outils CI/CD similaires.
|
||
|
||
1. **Exporter le contenu source** : extrayez les fichiers MDX à traduire.
|
||
2. **Envoyer aux traducteurs** : transmettez les fichiers à votre prestataire de traduction.
|
||
3. **Recevoir les traductions** : récupérez les fichiers MDX traduits.
|
||
4. **Importer et déployer** : ajoutez les fichiers traduits aux répertoires de langue et mettez à jour la navigation.
|
||
|
||
Ce processus GitHub Actions exporte automatiquement le contenu anglais modifié pour traduction lorsque des PR sont fusionnées dans `main`.
|
||
|
||
```yaml .github/workflows/export-for-translation.yml
|
||
name: Export content for translation
|
||
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
paths:
|
||
- '*.mdx'
|
||
- '!es/**'
|
||
- '!fr/**'
|
||
- '!zh/**'
|
||
|
||
# Prevent concurrent workflow runs to avoid race conditions
|
||
concurrency:
|
||
group: translation-export-${{ github.ref }}
|
||
cancel-in-progress: false
|
||
|
||
jobs:
|
||
export:
|
||
runs-on: ubuntu-latest
|
||
|
||
# Early exit if no changes detected (optional - acts as additional safety)
|
||
outputs:
|
||
files-changed: ${{ steps.changed.outputs.has-files }}
|
||
|
||
steps:
|
||
- name: Checkout repository
|
||
uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 2
|
||
|
||
- name: Get changed MDX files
|
||
id: changed
|
||
run: |
|
||
# Check if parent commit exists (handles initial push)
|
||
if ! git rev-parse HEAD~1 >/dev/null 2>&1; then
|
||
echo "has-files=false" >> $GITHUB_OUTPUT
|
||
echo "files=" >> $GITHUB_OUTPUT
|
||
echo "No parent commit found - skipping export"
|
||
exit 0
|
||
fi
|
||
|
||
# Get list of changed MDX files (excluding translation dirs)
|
||
files=$(git diff --name-only HEAD~1 HEAD -- '*.mdx' ':!es/' ':!fr/' ':!zh/' | tr '\n' ' ')
|
||
|
||
if [ -z "$files" ]; then
|
||
echo "has-files=false" >> $GITHUB_OUTPUT
|
||
echo "files=" >> $GITHUB_OUTPUT
|
||
echo "No MDX files changed - skipping export"
|
||
else
|
||
echo "has-files=true" >> $GITHUB_OUTPUT
|
||
echo "files=$files" >> $GITHUB_OUTPUT
|
||
echo "Found changed files: $files"
|
||
fi
|
||
shell: bash
|
||
|
||
- name: Create translation package directory
|
||
if: steps.changed.outputs.has-files == 'true'
|
||
run: |
|
||
mkdir -p translation-export
|
||
echo "Created translation-export directory"
|
||
|
||
- name: Copy changed files to export directory
|
||
if: steps.changed.outputs.has-files == 'true'
|
||
run: |
|
||
failed_count=0
|
||
for file in ${{ steps.changed.outputs.files }}; do
|
||
if [ -f "$file" ]; then
|
||
target_dir="translation-export/$(dirname "$file")"
|
||
mkdir -p "$target_dir"
|
||
cp "$file" "$target_dir/"
|
||
echo "✓ Copied: $file"
|
||
else
|
||
echo "✗ File not found: $file"
|
||
((failed_count++))
|
||
fi
|
||
done
|
||
|
||
if [ $failed_count -gt 0 ]; then
|
||
echo "Warning: $failed_count file(s) could not be copied"
|
||
fi
|
||
shell: bash
|
||
|
||
- name: Validate translation package
|
||
if: steps.changed.outputs.has-files == 'true'
|
||
run: |
|
||
echo "Translation package contents:"
|
||
find translation-export -type f -name "*.mdx" | sort
|
||
echo ""
|
||
file_count=$(find translation-export -type f -name "*.mdx" | wc -l)
|
||
echo "Total MDX files: $file_count"
|
||
|
||
- name: Upload translation package
|
||
if: steps.changed.outputs.has-files == 'true'
|
||
uses: actions/upload-artifact@v4
|
||
with:
|
||
name: translation-export-${{ github.sha }}
|
||
path: translation-export/
|
||
retention-days: 30
|
||
if-no-files-found: error
|
||
compression-level: 9
|
||
|
||
- name: Print job summary
|
||
if: steps.changed.outputs.has-files == 'true'
|
||
run: |
|
||
echo "## Translation Export Complete" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "**Artifact:** \`translation-export-${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "**Changed Files:**" >> $GITHUB_STEP_SUMMARY
|
||
echo "${{ steps.changed.outputs.files }}" | tr ' ' '\n' | sed 's/^/- /' >> $GITHUB_STEP_SUMMARY
|
||
```
|
||
|
||
Ce processus GitHub Actions valide et importe le contenu traduit lorsqu’il est ajouté via une PR.
|
||
|
||
```yaml .github/workflows/import-translations.yml
|
||
name: Import translations
|
||
|
||
on:
|
||
pull_request:
|
||
paths:
|
||
- 'es/**'
|
||
- 'fr/**'
|
||
- 'zh/**'
|
||
|
||
# Define explicit permissions
|
||
permissions:
|
||
contents: read
|
||
pull-requests: write
|
||
|
||
jobs:
|
||
validate:
|
||
runs-on: ubuntu-latest
|
||
|
||
outputs:
|
||
validation-status: ${{ steps.final-check.outputs.status }}
|
||
|
||
steps:
|
||
- name: Checkout repository
|
||
uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0 # Full history to ensure origin/main is available
|
||
|
||
- name: Fetch origin/main reference
|
||
run: |
|
||
git fetch origin main:origin/main 2>/dev/null || echo "origin/main not available, using latest"
|
||
continue-on-error: true
|
||
|
||
- name: Get changed translation files
|
||
id: changed-files
|
||
run: |
|
||
# Get all changed MDX files in translation directories
|
||
files=$(git diff --name-only origin/main..HEAD -- 'es/**/*.mdx' 'fr/**/*.mdx' 'zh/**/*.mdx' | sort)
|
||
|
||
if [ -z "$files" ]; then
|
||
echo "No translation MDX files detected in this PR"
|
||
echo "files=" >> $GITHUB_OUTPUT
|
||
echo "count=0" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "Found $(echo "$files" | wc -l) translation files"
|
||
echo "$files"
|
||
echo "files=$files" >> $GITHUB_OUTPUT
|
||
echo "count=$(echo "$files" | wc -l)" >> $GITHUB_OUTPUT
|
||
fi
|
||
shell: bash
|
||
|
||
- name: Validate frontmatter
|
||
id: frontmatter
|
||
if: steps.changed-files.outputs.count > 0
|
||
run: |
|
||
failed_files=()
|
||
success_count=0
|
||
total=${{ steps.changed-files.outputs.count }}
|
||
|
||
while IFS= read -r file; do
|
||
if [ ! -f "$file" ]; then
|
||
echo "✗ File not found: $file"
|
||
failed_files+=("$file")
|
||
continue
|
||
fi
|
||
|
||
# Check for valid frontmatter (lines 1-2 must be ---)
|
||
first_line=$(sed -n '1p' "$file")
|
||
second_line=$(sed -n '2p' "$file")
|
||
last_line=$(awk 'NF' "$file" | tail -1)
|
||
|
||
if [ "$first_line" = "---" ] && grep -q "^---$" "$file"; then
|
||
echo "✓ Valid frontmatter: $file"
|
||
((success_count++))
|
||
else
|
||
echo "✗ Invalid frontmatter in $file"
|
||
echo " Line 1: '$first_line'"
|
||
failed_files+=("$file")
|
||
fi
|
||
done <<< "${{ steps.changed-files.outputs.files }}"
|
||
|
||
echo ""
|
||
echo "Frontmatter check: $success_count/$total passed"
|
||
|
||
if [ ${#failed_files[@]} -gt 0 ]; then
|
||
echo "frontmatter_valid=false" >> $GITHUB_OUTPUT
|
||
printf 'failed_files=%s\n' "${failed_files[@]}" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "frontmatter_valid=true" >> $GITHUB_OUTPUT
|
||
fi
|
||
shell: bash
|
||
|
||
- name: Check file structure
|
||
id: structure
|
||
if: steps.changed-files.outputs.count > 0
|
||
run: |
|
||
missing_sources=()
|
||
orphaned_count=0
|
||
|
||
while IFS= read -r translated_file; do
|
||
# Extract language and relative path
|
||
# e.g., "es/docs/guide.mdx" -> lang="es", relative_path="docs/guide.mdx"
|
||
lang=$(echo "$translated_file" | cut -d'/' -f1)
|
||
relative_path=$(echo "$translated_file" | cut -d'/' -f2-)
|
||
source_file="$relative_path"
|
||
|
||
if [ ! -f "$source_file" ]; then
|
||
echo "Missing source: $translated_file -> $source_file"
|
||
missing_sources+=("$translated_file")
|
||
((orphaned_count++))
|
||
else
|
||
echo "✓ Found source: $translated_file -> $source_file"
|
||
fi
|
||
done <<< "${{ steps.changed-files.outputs.files }}"
|
||
|
||
echo ""
|
||
echo "Structure check: $orphaned_count orphaned file(s)"
|
||
|
||
if [ $orphaned_count -gt 0 ]; then
|
||
echo "structure_valid=false" >> $GITHUB_OUTPUT
|
||
printf 'missing_sources=%s\n' "${missing_sources[@]}" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "structure_valid=true" >> $GITHUB_OUTPUT
|
||
fi
|
||
shell: bash
|
||
|
||
- name: Validate file integrity
|
||
id: integrity
|
||
if: steps.changed-files.outputs.count > 0
|
||
run: |
|
||
integrity_passed=true
|
||
|
||
while IFS= read -r file; do
|
||
# Check file is readable and not empty
|
||
if [ ! -r "$file" ] || [ ! -s "$file" ]; then
|
||
echo "✗ File integrity issue: $file (not readable or empty)"
|
||
integrity_passed=false
|
||
fi
|
||
|
||
# Basic check: file should have content after frontmatter
|
||
line_count=$(wc -l < "$file")
|
||
if [ "$line_count" -lt 5 ]; then
|
||
echo "File is suspiciously short: $file ($line_count lines)"
|
||
fi
|
||
done <<< "${{ steps.changed-files.outputs.files }}"
|
||
|
||
if [ "$integrity_passed" = true ]; then
|
||
echo "integrity_valid=true" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "integrity_valid=false" >> $GITHUB_OUTPUT
|
||
fi
|
||
shell: bash
|
||
|
||
- name: Generate validation report
|
||
if: always()
|
||
run: |
|
||
echo "## Translation Validation Report" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "**Files Changed:** ${{ steps.changed-files.outputs.count }}" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
|
||
if [ "${{ steps.changed-files.outputs.count }}" = "0" ]; then
|
||
echo "No translation MDX files found in this PR" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
echo "> This could mean:" >> $GITHUB_STEP_SUMMARY
|
||
echo "- Only non-MDX files in es/, fr/, or zh/ directories were changed" >> $GITHUB_STEP_SUMMARY
|
||
echo "- Workflow was triggered but no translation content to validate" >> $GITHUB_STEP_SUMMARY
|
||
else
|
||
echo "### Validation Results" >> $GITHUB_STEP_SUMMARY
|
||
echo "- Frontmatter: ${{ steps.frontmatter.outputs.frontmatter_valid }}" >> $GITHUB_STEP_SUMMARY
|
||
echo "- File Structure: ${{ steps.structure.outputs.structure_valid }}" >> $GITHUB_STEP_SUMMARY
|
||
echo "- File Integrity: ${{ steps.integrity.outputs.integrity_valid }}" >> $GITHUB_STEP_SUMMARY
|
||
echo "" >> $GITHUB_STEP_SUMMARY
|
||
fi
|
||
shell: bash
|
||
|
||
- name: Final validation check
|
||
id: final-check
|
||
# Only run this check if we actually had MDX files to validate
|
||
if: steps.changed-files.outputs.count > 0
|
||
run: |
|
||
validation_failed=false
|
||
|
||
if [ "${{ steps.frontmatter.outputs.frontmatter_valid }}" != "true" ]; then
|
||
echo "Frontmatter validation failed"
|
||
validation_failed=true
|
||
fi
|
||
|
||
if [ "${{ steps.structure.outputs.structure_valid }}" != "true" ]; then
|
||
echo "File structure validation failed"
|
||
validation_failed=true
|
||
fi
|
||
|
||
if [ "${{ steps.integrity.outputs.integrity_valid }}" != "true" ]; then
|
||
echo "File integrity validation failed"
|
||
validation_failed=true
|
||
fi
|
||
|
||
if [ "$validation_failed" = true ]; then
|
||
echo "status=failed" >> $GITHUB_OUTPUT
|
||
exit 1
|
||
else
|
||
echo "status=passed" >> $GITHUB_OUTPUT
|
||
echo "All validations passed"
|
||
fi
|
||
shell: bash
|
||
|
||
- name: Handle no-files-to-validate case
|
||
# Run only when there are no MDX files to validate
|
||
if: steps.changed-files.outputs.count == 0
|
||
run: |
|
||
echo "No translation MDX files to validate - PR is valid"
|
||
echo "status=no-changes" >> ${{ steps.final-check.outputs }}
|
||
shell: bash
|
||
```
|
||
|
||
**Bonnes pratiques pour les processus de traduction externes**
|
||
|
||
- **Préserver le frontmatter** : assurez-vous que les traducteurs conservent le frontmatter YAML intact et ne traduisent que les valeurs de `title` et `description`.
|
||
- **Protéger les code blocks** : indiquez à vos prestataires que les code blocks ne doivent pas être traduits.
|
||
- **Utiliser la mémoire de traduction** : fournissez des glossaires contenant les termes techniques qui doivent rester en anglais ou avoir des traductions spécifiques.
|
||
- **Automatiser la validation** : utilisez des vérifications CI pour valider la syntaxe MDX et le frontmatter avant d’intégrer les traductions.
|
||
- **Contrôle de version** : suivez la version source de chaque traduction afin d’identifier le contenu obsolète.
|
||
|
||
<div id="images-and-media">
|
||
### Images et médias
|
||
</div>
|
||
|
||
Stockez les images traduites dans des répertoires propres à chaque langue.
|
||
|
||
```
|
||
images/
|
||
├── dashboard.png # Version anglaise
|
||
├── fr/
|
||
│ └── dashboard.png # French version
|
||
└── es/
|
||
└── dashboard.png # Spanish version
|
||
```
|
||
|
||
Référencez les images à l’aide de chemins relatifs dans vos contenus traduits.
|
||
|
||
```mdx es/index.mdx
|
||

|
||
```
|
||
|
||
|
||
<div id="seo-for-multi-language-sites">
|
||
## SEO pour les sites multilingues
|
||
</div>
|
||
|
||
Optimisez chaque version dans chaque langue pour les moteurs de recherche.
|
||
|
||
<div id="page-metadata">
|
||
### Metadata de la page
|
||
</div>
|
||
|
||
Incluez les metadata traduites dans le frontmatter de chaque fichier :
|
||
|
||
```mdx fr/index.mdx
|
||
---
|
||
title: "Commencer"
|
||
description: "Apprenez à commencer avec notre produit."
|
||
keywords: ["démarrage", "tutoriel", "guide"]
|
||
---
|
||
```
|
||
|
||
|
||
<div id="best-practices">
|
||
## Bonnes pratiques
|
||
</div>
|
||
|
||
<div id="date-and-number-formats">
|
||
### Formats de date et de nombre
|
||
</div>
|
||
|
||
Tenez compte des formats propres à chaque langue pour les dates et les nombres.
|
||
|
||
- Formats de date : MM/DD/YYYY (mois/jour/année) vs DD/MM/YYYY (jour/mois/année)
|
||
- Formats de nombres : 1,000.00 vs 1.000,00
|
||
- Symboles monétaires : $100.00 vs 100,00€
|
||
|
||
Incluez des exemples dans le format approprié pour chaque langue ou utilisez des formats universellement compréhensibles.
|
||
|
||
<div id="maintain-consistency">
|
||
### Maintenir la cohérence
|
||
</div>
|
||
|
||
- Assurez une parité de contenu entre toutes les langues afin que chaque utilisateur bénéficie de la même qualité d’information.
|
||
- Créez un glossaire de traduction pour les termes techniques.
|
||
- Conservez la même structure de contenu dans toutes les langues.
|
||
- Alignez le ton et le style sur ceux de votre contenu source.
|
||
- Utilisez des branches Git pour gérer le travail de traduction séparément des mises à jour du contenu principal.
|
||
|
||
<div id="layout-differences">
|
||
### Différences de mise en page
|
||
</div>
|
||
|
||
Certaines langues nécessitent plus ou moins d’espace que l’anglais. Testez votre contenu traduit sur différentes tailles d’écran pour vous assurer que :
|
||
|
||
- La navigation s’affiche correctement.
|
||
- Les code blocks ne débordent pas.
|
||
- Les tableaux et autres éléments de texte mis en forme restent lisibles.
|
||
- Les images se redimensionnent correctement.
|
||
|
||
<div id="character-encoding">
|
||
### Encodage des caractères
|
||
</div>
|
||
|
||
Assurez-vous que votre environnement de développement et votre pipeline de déploiement prennent en charge l’UTF-8 afin d’afficher correctement tous les caractères dans les langues utilisant différents alphabets et caractères spéciaux.
|
||
|
||
<div id="frequently-asked-questions">
|
||
## Questions fréquemment posées
|
||
</div>
|
||
|
||
<AccordionGroup>
|
||
<Accordion title="Dois-je traduire chaque page avant de lancer une nouvelle langue ?">
|
||
Non. Vous pouvez lancer une langue avec une couverture partielle et l’enrichir au fil du temps. Une approche courante consiste à traduire d’abord vos pages les plus visitées — généralement le contenu de prise en main, l’authentification et les principaux guides pratiques — et à laisser le contenu de référence moins fréquenté dans la langue par défaut jusqu’à ce que les traductions soient prêtes. Les utilisateurs préfèrent généralement un contenu partiellement traduit plutôt qu’aucune traduction.
|
||
</Accordion>
|
||
|
||
<Accordion title="Que se passe-t-il lorsqu’une page traduite est manquante ?">
|
||
Si un utilisateur accède à une URL traduite qui n’existe pas, il verra une erreur 404. Pour éviter cela, n’incluez que les pages traduites dans votre navigation spécifique à la langue ou maintenez la parité entre votre langue par défaut et le contenu traduit. Utiliser la même structure de fichiers dans toutes les langues facilite l’identification des traductions manquantes.
|
||
</Accordion>
|
||
|
||
<Accordion title="Les libellés de navigation doivent-ils être traduits ?">
|
||
Oui. Les libellés de navigation — noms de groupes, titres d’onglets, textes d’ancrage — doivent correspondre à la langue du contenu. Un libellé « Getting started » en anglais dans une section de documentation en espagnol crée une expérience incohérente. Mintlify prend en charge les structures de navigation spécifiques à chaque langue, de sorte que chaque langue peut avoir des libellés entièrement traduits.
|
||
</Accordion>
|
||
|
||
<Accordion title="Comment gérer les exemples de code dans le contenu traduit ?">
|
||
Le code lui-même ne doit pas être traduit — les noms de variables, les appels de fonctions et la syntaxe sont indépendants de la langue. Les commentaires dans les code blocks peuvent être traduits s’ils expliquent des concepts que les utilisateurs doivent comprendre. Les instructions entourant les code blocks doivent être entièrement traduites.
|
||
</Accordion>
|
||
|
||
<Accordion title="Mintlify prend-il en charge les langues de droite à gauche comme l’arabe ou l’hébreu ?">
|
||
Oui. L’arabe (`ar`) et l’hébreu (`he`) figurent dans la liste des codes de langue pris en charge. Mintlify gère automatiquement la mise en page RTL lorsque ces codes de langue sont configurés. Testez votre documentation en RTL pour vérifier que la navigation, les tableaux et les code blocks s’affichent correctement.
|
||
</Accordion>
|
||
</AccordionGroup> |