
Automating GitBook translations with GitHub Actions: A complete guide
Arthur Dufour
GitBook is a modern documentation platform that makes it easy to create, edit, and organize documentation. With its clean interface, version control, and collaboration features, it's no wonder it's become so popular among development teams.
But if you're managing documentation with GitBook and need to support multiple languages, you've probably hit a major roadblock: GitBook doesn't offer native translation capabilities. While it's fantastic for creating and managing documentation, this lack of built-in translation features can be a real headache for global teams.
In this article, I'll share a complete solution for automating GitBook translations using GitHub Actions and a custom Node.js script. As a fullstack developer who recently implemented this for my startup, I discovered that while GitBook does provide some documentation on translation workflows, it lacks the concrete implementation details you need to actually get it working.
This guide is for you if you:
By the end, you'll have everything you need to build a fully automated system that detects changes to your primary language content and automatically translates it to your target languages.
Before diving into implementation, you need to make two important decisions about your workflow:
You can enhance your translation process in many ways. For instance, you could just retranslate the specific phrases that changed instead of the entire file, though this would require more development work.
The solution I'm sharing creates an automated pipeline that:
Here's a diagram showing the complete workflow:

Before we can automate translations, we need to set up GitBook properly and connect it to GitHub using GitSync.
In GitBook, collections let you group related spaces together. For our translation workflow, we'll create a collection with a separate space for each language:
Next, we need to connect each space to our GitHub repository:
./en for the "English" space, and ./fr for the French space)Repeat this process for your target language space, making sure it's connected to the appropriate folder in your repository.
After setting up GitSync, your repository structure should look something like this:
/
├── en/ # Primary language content (English)
├── fr/ # French translations
└── .github/
└── workflows/
└── translate.yml # Our future GitHub Action workflow
This structure makes it easy to manage content for each language separately while keeping the automation in a central location.
Now, let's create the GitHub Action workflow that will detect changes and trigger our translation process.
Create a file at .github/workflows/translate.yml with the following content:
name: Translate GitBook Content
inputs:
source_language:
description: 'The source language (e.g.: en)'
required: true
target_language:
description: 'The target language (e.g.: fr)'
required: true
translator_api_key:
description: The Azure Translator API key
required: true
runs:
using: composite
steps:
- name: Get all changed markdown files
id: changed-markdown-files
uses: tj-actions/changed-files@v45
with:
files: |
${{ inputs.source_language }}/**/*.md
- name: Get all changes in .gitbook/
id: changed-gitbook-files
uses: tj-actions/changed-files@v45
with:
files: |
${{ inputs.source_language }}/.gitbook/**
- name: Copy .gitbook files to target language directory
shell: bash
if: steps.changed-gitbook-files.outputs.any_changed == 'true'
run: |
rm -rf ${{ inputs.target_language }}/.gitbook
mkdir -p ${{ inputs.target_language }}/.gitbook
cp -r ${{ inputs.source_language }}/.gitbook/* ${{ inputs.target_language }}/.gitbook/
- name: Setup Node.js
if: steps.changed-markdown-files.outputs.any_changed == 'true'
uses: actions/setup-node@v4
with:
node-version: 23.6.0
- name: Set up pnpm
if: steps.changed-markdown-files.outputs.any_changed == 'true'
uses: pnpm/action-setup@v4
with:
version: 9.14.2
- name: Install dependencies
shell: bash
if: steps.changed-markdown-files.outputs.any_changed == 'true'
working-directory: 365talents-actions/actions/gitbook-translator/translator-script
run: pnpm install
- name: Run translation script
shell: bash
if: steps.changed-markdown-files.outputs.any_changed == 'true'
working-directory: 365talents-actions/actions/gitbook-translator/translator-script
env:
SOURCE_LANGUAGE: ${{ inputs.source_language }}
TARGET_LANGUAGE: ${{ inputs.target_language }}
NEW_FILES: ${{ steps.changed-markdown-files.outputs.all_changed_files }}
TRANSLATOR_API_KEY: ${{ inputs.translator_api_key }}
run: node index.ts
# Make sure that deleting a file in the source_language also deletes it in target_language
- name: Cleanup deleted files
shell: bash
run: |
cd ${{ inputs.target_language }}
find . -type f -name "*.md" | while read file; do
if [ ! -f "../${{ inputs.source_language }}/$file" ]; then
rm "$file"
echo "Removed ${{ inputs.target_language }}/$file as it no longer exists in ${{ inputs.source_language }}/"
fi
done
# Commit translated content
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: Translate files
file_pattern: '${{ inputs.target_language }}/**'
add_options: --all
This workflow:
Now we need to develop the Node.js script that will perform the actual translation work. This script is the heart of our automation system, responsible for:
I've created a complete implementation of this translation script and shared it in a GitHub Gist for you to reference: GitBook Translation Script
The script uses Azure Translator API to convert content between languages, but you can easily modify it to work with other translation services like DeepL, Google Cloud Translation, or OpenAI if those better suit your needs.
One critical aspect of the translation script is how it handles Markdown syntax. The Azure Translator API sometimes loses Markdown formatting during translation. To fix this, the script uses regular expressions and string replacements to preserve all Markdown syntax elements after translation.
Remember that this implementation reflects my team's specific requirements and workflow. You should review and customize the code to match your team's translation strategy, especially regarding how you want to handle content updates and translation reviews.
The GitHub Action workflow automatically commits the translated files back to your repository. GitSync then updates your GitBook spaces with the new content. You have nothing more to do! 😄
My script currently only supports one target language, but it can easily be adapted to handle multiple target languages.
You would need to:
Currently, the described setup doesn't include a manual review process, meaning all new files are automatically translated and instantly added to GitBook.
To implement a manual review process, you could:
Our setup only translates new files, which isn't ideal for frequently updated documentation. If you regularly make changes to your documentation, you'd need to implement incremental translation to process only the content that has changed.
Azure Translator, like other machine translation services, works well for most general content but may struggle with:
For technical documentation, you might notice certain specialized terms being translated incorrectly or inconsistently across documents.
Beyond manual review, here are several strategies to enhance your translation quality:
When implementing an automated translation system, it's important to consider the costs involved, especially as your documentation grows.
A few things to keep in mind:
Setting up this GitBook translation system was honestly not that simple to do. GitBook really should just build this in. In my opinion, documentation is global, and teams shouldn't have to hack together custom solutions for something so fundamental.
Until then, this solution works well enough to save you from manual translation headaches. It's not perfect, but it's definitely better than copying and pasting content between languages!