i18n - Usando Crowdin
O sistema i18n do Docusaurus é desacoplado de qualquer software de tradução.
Você pode integrar o Docusaurus com as ferramentas e SaaS de sua escolha, contanto que coloque os arquivos de tradução no local correto.
Nós documentamos o uso de Crowdin, como um possível exemplo de integração.
This is not an endorsement of Crowdin as the unique choice to translate a Docusaurus site, but it is successfully used by Facebook to translate documentation projects such as Jest, Docusaurus, and ReasonML.
Consulte a documentação do Crowdin e suporte do Crowdin para obter ajuda.
Use this community-driven GitHub discussion to discuss anything related to Docusaurus + Crowdin.
Visão geral do Crowdin
Crowdin é uma tradução SaaS, oferecendo um plano gratuito para projetos de código aberto.
Recomendamos o seguinte fluxo de trabalho de tradução:
- Carregar arquivos fontes para Crowdin (arquivos não traduzidos)
- Use o Crowdin para traduzir o conteúdo
- Baixar traduções do Crowdin (arquivos de tradução localizados)
Crowdin fornece uma CLI para carregar fontes e baixar traduções, permitindo que você automatize o processo de tradução.
The crowdin.yml
configuration file is convenient for Docusaurus, and permits to download the localized translation files at the expected location (in i18n/[locale]/..
).
Leia a documentação oficial para saber mais sobre recursos avançados e diferentes fluxos de trabalho de tradução.
Tutorial do Crowdin
This is a walk-through of using Crowdin to translate a newly initialized English Docusaurus website into French, and assume you already followed the i18n tutorial.
O resultado final pode ser visto no docusaurus-crowdin-example.netlify.app (repositório).
Preparar o site do Docusaurus
Inicializar um novo site do Docusaurus:
npx create-docusaurus@latest website classic
Adicione a configuração do site para o idioma francês:
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},
themeConfig: {
navbar: {
items: [
// ...
{
type: 'localeDropdown',
position: 'left',
},
// ...
],
},
},
// ...
};
Traduzir a página inicial:
import React from 'react';
import Translate from '@docusaurus/Translate';
import Layout from '@theme/Layout';
export default function Home() {
return (
<Layout>
<h1 style={{margin: 20}}>
<Translate description="The homepage main heading">
Welcome to my Docusaurus translated site!
</Translate>
</h1>
</Layout>
);
}
Crie um projeto Crowdin
Faça uma conta em Crowdin e crie um projeto.
Use English as the source language, and French as the target language.
Seu projeto foi criado, mas está vazio por enquanto. Enviaremos o upload dos arquivos para traduzir nos próximos passos.
Crie a configuração Crowdin
Esta configuração (doc) fornece um mapeamento para a CLI Crowdin entender:
- Onde encontrar os arquivos de origem a serem carregados (JSON e Markdown)
- Where to download the files after translation (in
i18n/[locale]
)
Criar crowdin.yml
no site
:
project_id: '123456'
api_token_env: CROWDIN_PERSONAL_TOKEN
preserve_hierarchy: true
files:
# JSON translation files
- source: /i18n/en/**/*
translation: /i18n/%two_letters_code%/**/%original_file_name%
# Docs Markdown files
- source: /docs/**/*
translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name%
# Blog Markdown files
- source: /blog/**/*
translation: /i18n/%two_letters_code%/docusaurus-plugin-content-blog/**/%original_file_name%
Crowdin tem sua própria sintaxe para declarar caminhos de origem/tradução:
**/*
: tudo em uma subpasta%two_letters_code%
: a variante de 2 letras dos idiomas de destino do Crowdin (fr
no nosso caso)**/%original_file_name%
: as traduções irão preservar a pasta/hierarquia de arquivos original
Os avisos Crowdin CLI nem sempre são fáceis de entender.
Aconselhamos a:
- alterar uma coisa de cada vez
- re-enviar fontes após qualquer alteração de configuração
- usar caminhos que começam com
/
(./
não funciona) - evitar padrões de globalização extravagantes como
/docs/**/*.(md|mdx)
(não funciona)
Token de acesso
O atributo api_token_env
define o nome da variável env lido pelo Crowdin CLI.
Você pode obter um Token de Acesso Pessoal
em página de seu perfil pessoal.
Você pode manter o valor padrão CROWDIN_PERSONAL_TOKEN
, e definir esta variável de ambiente e no seu computador e no servidor CI para o token de acesso gerado.
Um Token de acesso pessoal concede acesso de leitura e escrita a todos os seus projetos no Crowdin.
Você não deve fazer commitar isso, e pode ser uma boa ideia criar um dedicado perfil Crowdin para a sua empresa em vez de usar uma conta pessoal.
Outros campos de conifuração
project_id
: pode ser codificado e é encontrado emhttps://crowdin.com/project/<MY_PROJECT_NAME>/settings#api
preserve_hierarchy
: preservar a hierarquia da pasta de sua documentação na interface do Crowdin em vez de nivelar tudo
Instalar o Crowdin CLI
This tutorial uses the CLI version 3.5.2
, but we expect 3.x
releases to keep working.
Install the Crowdin CLI as an npm package to your Docusaurus site:
- npm
- Yarn
- pnpm
npm install @crowdin/cli@3
yarn add @crowdin/cli@3
pnpm add @crowdin/cli@3
Adicione um script do Crowdin
:
{
"scripts": {
// ...
"write-translations": "docusaurus write-translations",
"crowdin": "crowdin"
}
}
Teste se você pode executar o Crowdin CLI:
- npm
- Yarn
- pnpm
npm run crowdin -- --version
yarn crowdin --version
pnpm run crowdin -- --version
Defina a variável env CROWDIN_PERSONAL_TOKEN
no seu computador, para permitir que o CLI se autentique com a API Crowdin.
Temporariamente, você pode codificar o seu token pessoal em crowdin.yml
com api_token: 'MEU-TOKEN'
.
Faça upload dos arquivos fontes
Gere os arquivos de tradução JSON para a língua padrão no website/i18n/en
:
- npm
- Yarn
- pnpm
npm run write-translations
yarn write-translations
pnpm run write-translations
Carregar todos os arquivos de tradução JSON e Markdown:
- npm
- Yarn
- pnpm
npm run crowdin upload
yarn crowdin upload
pnpm run crowdin upload
Seus arquivos de origem agora são visíveis na interface Crowdin: https://crowdin.com/project/<MY_PROJECT_NAME>/settings#files
Traduza os arquivos fontes
Em https://crowdin.com/project/<MY_PROJECT_NAME>
, clique na língua-alvo francesa.
Traduza alguns arquivos do Markdown.
Use Hide String
para garantir que os tradutores não traduzam coisas que não devem:
- Front matter:
id
,slug
,tags
... - Avisos:
:::
,:::note
,:::tip
...
Traduza alguns arquivos JSON.
O atributo description
dos arquivos de tradução JSON é visível no Crowdin para ajudar a traduzir as strings.
**Pré-traduza ** seu site e corrija os erros de pré-tradução manualmente (primeiro habilite a Memória de Tradução Global nas configurações).
Use primeiro o recurso Hide String
pois o Crowdin está pré-traduzindo as coisas muito otimisticamente.
Baixe as tradu ções
Use o Crowdin CLI para baixar os arquivos traduzidos JSON e Markdown.
- npm
- Yarn
- pnpm
npm run crowdin download
yarn crowdin download
pnpm run crowdin download
O conteúdo traduzido deve ser baixado em i18n/fr
.
Inicie seu site na localidade francesa:
- npm
- Yarn
- pnpm
npm run start -- --locale fr
yarn run start --locale fr
pnpm run start -- --locale fr
Make sure that your website is now translated in French at http://localhost:3000/fr/
.
Automatizar com CI
We will configure the CI to download the Crowdin translations at build time and keep them outside of Git.
Adicione website/i18n
ao .gitignore
.
Defina a variável de ambiente CROWDIN_PERSONAL_TOKEN
no seu CI.
Create an npm script to sync
Crowdin (extract sources, upload sources, download translations):
{
"scripts": {
"crowdin:sync": "docusaurus write-translations && crowdin upload && crowdin download"
}
}
Chame o comando npm run crowdin:sync
no seu CI, logo antes de construir o site do Docusaurus.
Mantenha suas visualizações de implantação rápidas: não baixe traduções e use npm run build - --locale en
para ramificações de recursos.
Crowdin não suporta bem múltiplos uploads/downloads simultâneos: é preferível incluir apenas traduções para sua implantação de produção e manter as visualizações de implantação não traduzidas.
Tópicos avançados do Crowdin
MDX
Preste atenção especial aos fragmentos JSX em documentos MDX!
Crowdin não oferece suporte oficialmente para MDX, mas adicionou ** suporte para a extensão .mdx
**, e interpretar esses arquivos como Markdown (em vez de texto simples).
Problemas MDX
Crowdin thinks that the JSX syntax is embedded HTML and can mess up with the JSX markup when you download the translations, leading to a site that fails to build due to invalid JSX.
Simple JSX fragments using simple string props like <Username name="Sebastien"/>
will work fine; more complex JSX fragments using object/array props like <User person={{name: "Sebastien"}}/>
are more likely to fail due to a syntax that does not look like HTML.
Soluções MDX
We recommend extracting the complex embedded JSX code as separate standalone components. We also added an mdx-code-block
escape hatch syntax:
# How to deploy Docusaurus
To deploy Docusaurus, run the following command:
````mdx-code-block
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="bash" label="Bash">
```bash
GIT_USER=<GITHUB_USERNAME> yarn deploy
```
</TabItem>
<TabItem value="windows" label="Windows">
```batch
cmd /C "set "GIT_USER=<GITHUB_USERNAME>" && yarn deploy"
```
</TabItem>
</Tabs>
````
Isso vai:
- ser interpretado pelo Crowdin como um código de blocos (e não enviar mensagens com a marcação no download)
- ser interpretado pelo Docusaurus como JSX normal (como se ele não fosse envolvido por nenhum bloco de código)
- infelizmente opt-out na ferramenta MDX (destaque de sintaxe IDE, Prettier...)
Controle de versão dos documentos
Configurar arquivos de tradução para a pasta website/versioned_docs
.
Ao criar uma nova versão, as strings de origem geralmente serão bastante semelhantes à versão atual (website/docs
) e você não quer traduzir a nova documentação de versão de novo e de novo.
Crowdin fornece uma configuração Strings duplicadas
.
Recomendamos usar Hide
, mas a configuração ideal depende da quantidade de versões diferentes.
Não usar Hide
leva a um valor muito maior de strings de origem
em quotas, e afetará os preços.
Plugins de multi-instância
Você precisa configurar os arquivos de tradução para cada instância do plugin.
Se você tem uma instância do plugin de documentação com id=ios
, você precisará configurar esses arquivos de origem também
website/ios
website/ios_versioned_docs
(se versionado)
Mantendo o seu site
Às vezes, você removerá ou renomeará um arquivo de origem no Git, e o Crowdin exibirá avisos de CLI:
Quando as suas fontes são refatoradas, você deve usar a interface de usuário do Crowdin para atualizar seus arquivos Crowdin manualmente:
Integrações VCS (Git)
Crowdin tem várias integrações de VCS para GitHub, GitLab, Bitbucket.
Recomendamos evitá-los.
Poderia ter sido útil ser capaz de editar as traduções em Git e Crowdin, e ter uma sincronização bidirecional entre os 2 sistemas.
Na prática, não funcionou de maneira muito confiável por alguns motivos:
- O Crowdin -> Git sync funciona bem (com uma pull request)
- O Git -> sincronização Crowdin é manual (você tem que pressionar um botão)
- As heurísticas usadas pelo Crowdin para corresponder as traduções Markdown existentes com as fontes Markdown existentes não são 100% confiáveis, e você tem que verificar o resultado na Crowdin UI após qualquer sincronização do Git
- Ao mesmo tempo, edição de 2 usuários no Git e Crowdin pode levar a uma perda de tradução
- Requer que o arquivo
crowdin.yml
esteja na raiz do repositório
Localização contextual
Crowdin tem um recurso de localização contextual.
Infelizmente, ainda não funciona por razões técnicas, mas temos boas esperanças de que possa ser resolvido.
Crowdin replaces Markdown strings with technical IDs such as crowdin:id12345
, but it does so too aggressively, including hidden strings, and messes up with front matter, admonitions, JSX...
Localize edit URLs
Quando o usuário está navegando em uma página em /fr/doc1
, o botão de edição será vinculado por padrão ao documento não localizado em website/docs/doc1.md
.
You may prefer the edit button to link to the Crowdin interface instead by using the editUrl
function to customize the edit URLs on a per-locale basis.
const DefaultLocale = 'en';
module.exports = {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
editUrl: ({locale, versionDocsDirPath, docPath}) => {
// Link to Crowdin for French docs
if (locale !== DefaultLocale) {
return `https://crowdin.com/project/docusaurus-v2/${locale}`;
}
// Link to GitHub for English docs
return `https://github.com/facebook/docusaurus/edit/main/website/${versionDocsDirPath}/${docPath}`;
},
},
blog: {
editUrl: ({locale, blogDirPath, blogPath}) => {
if (locale !== DefaultLocale) {
return `https://crowdin.com/project/docusaurus-v2/${locale}`;
}
return `https://github.com/facebook/docusaurus/edit/main/website/${blogDirPath}/${blogPath}`;
},
},
},
],
],
};
Atualmente não é possível vincular a um arquivo específico no Crowdin.
Configuração de exemplo
O arquivo de configuração do Docusaurus v2 é um bom exemplo de como usar versionamento e multi-instância:
project_id: '428890'
api_token_env: CROWDIN_PERSONAL_TOKEN
preserve_hierarchy: true
languages_mapping: &languages_mapping
two_letters_code:
pt-BR: pt-BR
files:
- source: /website/i18n/en/**/*
translation: /website/i18n/%two_letters_code%/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/docs/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/community/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-docs-community/current/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/versioned_docs/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-docs/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/blog/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-blog/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/src/pages/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-pages/**/%original_file_name%
ignore: [/**/*.js, /**/*.jsx, /**/*.ts, /**/*.tsx, /**/*.css]
languages_mapping: *languages_mapping