Connecting GitHub to Phrase Strings lets developers and localization teams stop passing locale files back and forth by hand. New source strings get picked up automatically, translations come back as a pull request, and nobody has to interrupt a sprint to ask “is the German file ready yet.”
There are two ways to do this today, and which one fits depends on how your team ships software:
- Repo Sync — a UI-driven connection between a Phrase project and a GitHub repository. Best if you want a visual setup, project-level control, and translations delivered as pull requests without touching your CI config.
- The Phrase Strings GitHub Action — installs the Phrase CLI directly into your GitHub Actions workflow. Best if localization needs to be a first-class step in your existing CI/CD pipeline, not a parallel process.
Most teams end up using one as their primary sync and can add the other later. This guide covers both, plus a continuous localization workflow you can adapt to your branching model.
Before you start: create your .phrase.yml
Both methods rely on the same configuration file. .phrase.yml tells Phrase where your locale files live in your repository and how they map to the locales in your Phrase project. It sits in your project’s root folder.
You don’t need to write this by hand. Run phrase init from the Phrase CLI, and it’ll prompt you for a Phrase API access token (create one in your Phrase account settings) and generate a working config.
A basic config looks like this:
phrase:
project_id: your_project_id
push:
sources:
– file: ./config/locales/en.yml
params:
locale_id: en
file_format: yml
pull:
targets:
– file: ./config/locales/<locale_code>.yml
params:
file_format: yml
If only your developers should be creating new source strings, restrict the push source to your default locale, as shown above. For pulling, include every locale you support, including the default, since content editors sometimes fix typos directly in that file too.
Commit .phrase.yml to your repository. If you generated an access token to run phrase init locally, remove it from the file before committing: the GitHub Action authenticates via a repository secret instead, and Repo Sync doesn’t need it in the file at all.
Option 1: Set up Repo Sync
Repo Sync is the fastest way to connect a Phrase project to GitHub without editing your CI pipeline.
First, make sure your repository meets the prerequisites: read and write access for Phrase, a valid .phrase.yml at the root of the branch you want to monitor, and, if the target repository requires signed commits, GitHub App authentication rather than a personal access token (commits pushed via a personal access token aren’t signed, so the sync will fail on repositories that require verification).
To connect a repository:
- In Phrase, go to Automations → Repo Syncs (or open Integrations, scroll to Repo Sync, and click Configure).
- Click Add Sync/GitHub.
- Select the Phrase project you want to connect.
- Choose your authentication method: GitHub App (recommended), personal access token, or self-hosted instance. For the GitHub App, click Authenticate if it isn’t installed yet, or Manage installation if it already is; this is a one-time step and the same authentication can be reused across multiple repository syncs.
- Select the GitHub repository and the branch to sync (usually your main branch).
- Optionally, name the branch Phrase will use for pull requests. Leave it blank and Phrase defaults to phrase-translations.
- Click Validate Configuration to confirm your authentication and .phrase.yml are set up correctly.
- Optionally, set an Import behavior to control when new or updated files are automatically pulled into the project.
- Click Save.
Your project is now connected and listed on the Repo Syncs page. From there, use Import to pull new source strings into Phrase, and Export to open a pull request with the latest translations, once translators have completed their work. A History view on the same page tracks past imports and exports per project.
If a sync fails, the CLI is the fastest way to debug: run it locally against your .phrase.yml to surface the actual error before contacting support.
Option 2: Set up the Phrase Strings GitHub Action
If localization should live inside your CI/CD pipeline rather than beside it, use the Phrase Strings GitHub Action (https://developers.phrase.com/en/developer-tools/strings-github-action). It installs the Phrase CLI as a workflow step, so pushing and pulling translations becomes part of the same pipeline that builds and deploys your app.
steps:
– uses: actions/checkout@v4
– uses: phrase/setup-cli@v1
with:
version: 2.19.0
– run: phrase pull
– run: phrase push –wait
env:
PHRASE_ACCESS_TOKEN: ${{ secrets.PHRASE_ACCESS_TOKEN }}
Store your Phrase API access token as a GitHub Actions secret named PHRASE_ACCESS_TOKEN rather than committing it anywhere. The action reads your repository’s .phrase.yml for its push and pull configuration, so once that file is in place, this is close to the entire setup.
This approach suits teams who want zero manual steps after initial setup: new strings get pushed to Phrase automatically on every relevant build, and translated content pulls back in without anyone clicking a button.
A continuous localization workflow
However you connect GitHub, the workflow logic is similar. Here’s a common pattern for teams using feature branches and pull requests into a main branch:
- A developer adds new source strings while building a feature, using only the default locale.
- On merge to main (or on your chosen trigger), new keys reach Phrase, either automatically via Repo Sync’s Import behavior setting or through the GitHub Action’s phrase push.
- Translators see the new strings appear in Phrase and work through them, with full context if you’ve set up in-context preview.
- Completed translations come back to your repository, either as a pull request from Repo Sync’s Export, or via phrase pull in your pipeline.
- A developer reviews and merges the translation pull request, and the localized feature ships.
Keeping main deployable. There’s usually a gap between a feature merging and its translations coming back. If your main branch needs to be deployable at all times, a common fix is to merge feature branches into a shared development or staging branch first, then merge to main only once translations for that batch are in. Configure whichever branch you use for this in your Repo Sync or Action settings, not necessarily main itself.
Which one should you use?
If you’re not sure where to start: Repo Sync gets you running with a visual setup and no pipeline changes, which is often the quicker first step. If your team already treats infrastructure as code and wants localization to fail loudly in CI if something’s misconfigured, start with the GitHub Action instead. Many teams eventually run both, using the Action for automated pushes on every build and Repo Sync’s pull request flow for reviewing incoming translations.
FAQs
Can I use Repo Sync and the GitHub Action together?
Yes, and many teams do. A common pattern is using the GitHub Action to push new source strings to Phrase automatically on every build, then using Repo Sync’s pull request flow to review and merge translations as they come back. Both rely on the same `.phrase.yml` configuration, so there’s no conflict between running them side by side.
What happens if my repository requires signed commits?
Use GitHub App authentication rather than a personal access token. Commits pushed via a personal access token aren’t signed, so the sync will fail with the error “The repository requires verified (signed) commits.” The GitHub App method produces signed commits and works with this requirement.
How do I keep my main branch deployable while translations are in progress?
There’s usually a lag between a feature’s pull request merging and its translations coming back from Phrase. If your main branch needs to be deployable at all times, merge feature branches into a shared development or staging branch first, and only merge to main once translations for that batch are complete.
Do I need to set up a webhook for auto-import?
No. When you connect a repository through Repo Sync, you can set an Import behavior option to control when new or updated files are automatically pulled into your Phrase project. This replaces the manual webhook setup that earlier versions of this integration required.





