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.
caution
Isso é não é um endosso de Crowdin como a escolha única para traduzir um site Docusaurus, mas é usado com sucesso pelo Facebook para traduzir projetos de documentação como Jest, Docusaurus e ReasonML.
Consulte a documentação do Crowdin e suporte do Crowdin para obter ajuda.
tip
Use esta questão do GitHub conduzida pela comunidade para discutir qualquer coisa relacionada ao Docusaurus + Crowdin.
#
Visão geral do CrowdinCrowdin é 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.
O crowdin.yml
arquivo de configuração é conveniente para o Docusaurus, e permite baixar os arquivos de tradução localizados no local esperado (em i18n/<locale>/.
).
Leia a documentação oficial para saber mais sobre recursos avançados e diferentes fluxos de trabalho de tradução.
#
Tutorial do CrowdinEsse é um passo em frente no uso do Crowdin para traduzir um recém-iniciado site Docusaurus Inglês para o Francês, e assuma que você já seguiu o tutorial i18n.
O resultado final pode ser visto no docusaurus-crowdin-example.netlify.app (repositório).
#
Preparar o site do DocusaurusInicializar um novo site do Docusaurus:
npx @docusaurus/init@latest init 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 CrowdinFaça uma conta em Crowdin e crie um projeto.
Use o inglês como idioma de origem e o francês como idioma alvo.
Seu projeto foi criado, mas está vazio por enquanto. Enviaremos o upload dos arquivos para traduzir nos próximos passos.
#
Crie a configuração CrowdinEsta configuração (doc) fornece um mapeamento para a CLI Crowdin entender:
- Onde encontrar os arquivos de origem a serem carregados (JSON e Markdown)
- Onde baixar os arquivos após a tradução (em
i18n/<locale>
)
Criar crowdin.yml
no site
:
project_id: '123456'api_token_env: 'CROWDIN_PERSONAL_TOKEN'preserve_hierarchy: truefiles: [ # 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
info
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 acessoO 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.
tip
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.
caution
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çãoproject_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 CLIEste tutorial usa a CLI na versão 3.5.2
, mas esperamos que as versões 3.x
continuem funcionando.
Instale o Crowdin CLI como um pacote NPM no seu site Docusaurus:
- npm
- Yarn
npm install @crowdin/cli@3
yarn add @crowdin/cli@3
Adicione um script do Crowdin
:
{ "scripts": { "crowdin": "crowdin" }}
Teste se você pode executar o Crowdin CLI:
- npm
- Yarn
npm run crowdin -- --version
yarn 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.
tip
Temporariamente, você pode codificar o seu token pessoal em crowdin.yml
com api_token: 'MEU-TOKEN'
.
#
Faça upload dos arquivos fontesGere os arquivos de tradução JSON para a língua padrão no website/i18n/en
:
- npm
- Yarn
npm run write-translations
yarn run write-translations
Carregar todos os arquivos de tradução JSON e Markdown:
- npm
- Yarn
npm run crowdin upload
yarn 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 fontesEm https://crowdin.com/project/<MY_PROJECT_NAME>
, clique na língua-alvo francesa.
Traduza alguns arquivos do Markdown.
tip
Use Hide String
para garantir que os tradutores não traduzam coisas que não devem:
- Frontmatter:
id
,slug
,tags
... - Avisos:
:::
,:::note
,:::tip
...
Traduza alguns arquivos JSON.
info
O atributo description
dos arquivos de tradução JSON é visível no Crowdin para ajudar a traduzir as strings.
tip
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çõesUse o Crowdin CLI para baixar os arquivos traduzidos JSON e Markdown.
- npm
- Yarn
npm run crowdin download
yarn run crowdin download
O conteúdo traduzido deve ser baixado em i18n/fr
.
Inicie seu site na localidade francesa:
- npm
- Yarn
npm run start -- --locale fr
yarn run start -- --locale fr
Certifique-se de que seu site esteja traduzido em francês em http://localhost:3000/fr/
.
#
Automatizar com CIVamos configurar o CI para baixar as traduções Crowdin no horário de compilação, e mantê-las fora do Git.
Adicione website/i18n
ao .gitignore
.
Defina a variável de ambiente CROWDIN_PERSONAL_TOKEN
no seu CI.
Crie um script npm para sincronizar
Crowdin (extrair fontes, fazer upload de fontes, baixar traduções):
{ "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.
tip
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.
caution
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#
MDXcaution
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 MDXCrowdin pensa que a sintaxe JSX é HTML embutido e pode bagunçar a marcação JSX quando você baixa as traduções, levando a um site à falha na construção devido ao JSX inválido.
Fragmentos JSX simples usando propriedades de string simples como <Username name="Sebastien"/>
funcionarão bem.
Fragmentos JSX mais complexos usando propriedades de objeto/array como <User person={{name: "Sebastien"}}/>
têm mais probabilidade de falhar devido a uma sintaxe que não se parece com HTML.
#
Soluções MDXRecomendamos mover o código JSX incorporado complexo como componentes autônomos separados.
Também adicionamos uma sintaxe de escape mdx-code-block
:
# Como fazer deploy do Docusaurus
Para fazer deploy do Docusaurus, execute o seguinte comando:
````mdx-code-blockimport Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs defaultValue="bash" values={[ { label: 'Bash', value: 'bash' }, { label: 'Windows', value: 'windows' }]}> <TabItem value="bash">
```bash GIT_USER=<GITHUB_USERNAME> yarn deploy ```
</TabItem> <TabItem value="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 documentosConfigurar 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.
caution
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ânciaVocê 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.
warning
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 contextualCrowdin tem um recurso de localização contextual.
caution
Infelizmente, ainda não funciona por razões técnicas, mas temos boas esperanças de que possa ser resolvido.
Crowdin substitui strings de markdown por ids técnicos como crowdin: id12345
, mas faz de forma muito agressiva, incluindo strings ocultas e bagunçando com frontmatter, admoestações, jsx...
#
Localizar Urls de ediçãoQuando 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
.
Você pode preferir o botão de edição para vincular à interface do Crowdin, e pode usar a função editUrl
para personalizar os urls de edição por localidade.
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/master/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/master/website/${blogDirPath}/${blogPath}`; }, }, }, ], ],};
note
Atualmente não é possível vincular a um arquivo específico no Crowdin.
#
Configuração de exemploO 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: truelanguages_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, }, ]