Ir para o conteúdo principal
Version: 2.0.0-beta.8

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 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.

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 Crowdin

Esse é 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 Docusaurus

Inicializar um novo site do Docusaurus:

npm init [email protected] website classic

Adicione a configuração do site para o idioma francês:

docusaurus.config.js
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},
themeConfig: {
navbar: {
items: [
// ...
{
type: 'localeDropdown',
position: 'left',
},
// ...
],
},
},
// ...
};

Traduzir a página inicial:

src/pages/index.js
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 o inglês como idioma de origem e o francês como idioma alvo.

Crie um projeto Crowdin com o inglês como idioma de origem e o francês como idioma de destino

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)
  • Onde baixar os arquivos após a tradução (em i18n/<locale>)

Criar crowdin.yml no site:

crowdin.yml
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
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 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.

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ção

  • project_id: pode ser codificado e é encontrado em https://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

Este 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 install @crowdin/[email protected]

Adicione um script do Crowdin:

package.json
{
"scripts": {
"crowdin": "crowdin"
}
}

Teste se você pode executar o Crowdin CLI:

npm 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 fontes

Gere os arquivos de tradução JSON para a língua padrão no website/i18n/en:

npm run write-translations

Carregar todos os arquivos de tradução JSON e Markdown:

npm run crowdin upload

Crowdin CLI carregando arquivos fonte do Docusaurus

Seus arquivos de origem agora são visíveis na interface Crowdin: https://crowdin.com/project/<MY_PROJECT_NAME>/settings#files

Crowdin UI mostrando arquivos de origem do Docusaurus

Traduza os arquivos fontes

Em https://crowdin.com/project/<MY_PROJECT_NAME>, clique na língua-alvo francesa.

Crowdin UI mostrando arquivos de tradução em francês

Traduza alguns arquivos do Markdown.

Crowdin UI para traduzir um arquivo 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 ...

Crowdin UI ocultar string

Traduza alguns arquivos JSON.

Crowdin UI para traduzir um arquivo 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ções

Use o Crowdin CLI para baixar os arquivos traduzidos JSON e Markdown.

npm run crowdin download

O conteúdo traduzido deve ser baixado em i18n/fr.

Inicie seu site na localidade francesa:

npm run start -- --locale fr

Certifique-se de que seu site esteja traduzido em francês em http://localhost:3000/fr/.

Automatizar com CI

Vamos 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):

package.json
{
"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

MDX

caution

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 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 MDX

Recomendamos mover o código JSX incorporado complexo como componentes autônomos separados.

Também adicionamos uma sintaxe de escape mdx-code-block:

# 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.

Configuração da opção Crowdin para 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â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:

Crowdin CLI: download de aviso de tradução

Quando as suas fontes são refatoradas, você deve usar a interface de usuário do Crowdin para atualizar seus arquivos Crowdin manualmente:

Crowdin UI: renomeando um arquivo

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 contextual

Crowdin 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ção

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.

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.

docusaurus.config.js
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}`;
},
},
},
],
],
};
note

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:

crowdin.yml
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,
},
]