Skip to main content
Content sync moves files between a connected repository and a native project. A project’s Sync settings sync with GitLab. To sync a GitHub repository, use its Automation settings under Integrations → GitHub, or a visual workflow Content sync step. Connecting GitHub or GitLab gives Platform access to repositories. It does not start a file sync or generate translations.

Configure content sync

  1. Connect GitLab under Integrations.
  2. Open the project’s Settings and select Sync.
  3. Choose the repository, the repository folder that holds the source files, the project folder they should appear in, and the language file paths described below.
  4. Choose a schedule: only when you select Sync now, every hour, or every day. Then select Save.
  5. Select Sync now for the first run.
  6. Check the run under Recent syncs and confirm the source paths in Files.
Only one sync of a project runs at a time. GitHub shows in the Sync settings’ service picker but can’t be chosen there for now. Admins, localization managers, and developers can change the sync and start it. Other members with access to the project can see its settings and runs. Sync is available on every plan. Content sync automations created on the project’s Automations page before the Sync panel keep running. A visual workflow can also run a Content sync step, for GitHub or GitLab, when you need more steps around it. A GitHub step sends translations that are already ready back through a pull request; review it before merging.

Pull from GitLab

A workspace connected to GitLab, GitLab.com or its own server, can pull a repository’s source files into a project from the project’s Sync settings or with the visual workflow Content sync step, and send approved translations back as one merge request per sync.
  1. Connect GitLab under Integrations, with an access token whose user or group has the Developer role on the repository (Reporter pulls only; a project marked pull only in the repository list can’t receive merge requests). Runs use one of the workspace’s connections, not a member’s GitLab.com sign-in: with several connections, the Sync panel shows a GitLab connection field, and the sync keeps the connection it was saved with even if the default changes later.
  2. Open the project’s Settings, select Sync and choose GitLab as the repository service; or, in a visual workflow, add a Content sync step and choose GitLab as the source. Then pick the repository.
  3. Set the repository folder, the project folder, and Language file paths: where each language’s files sit under the repository folder, with {{locale}} standing for the language code, for example {{locale}}.json or {{locale}}/pages/*.html. Only the source language’s files are imported. A code in the repository names a project language the same way as in other integrations: the same tag whatever its case (pt-br is pt-BR), or the one project language of that family (fr for fr-FR); where the project has two, such as en-US and en-GB, a plain en file is skipped.
  4. Leave Branch empty to read the repository’s default branch.
Each run reads the branch’s latest commit. A file whose content hasn’t changed since the last run isn’t imported again, though its strings are still checked against the text already known. Keys the repository no longer has, and whole files it dropped, are hidden in the project, not deleted, so their translations stay and translation jobs skip them; a key that comes back is shown again. By default the repository’s source text replaces the project’s whenever the file changed. With the project setting Allow source text editing on, a run keeps source text edited in the project, takes changes made in the repository, and reports a string as a clash when both sides changed it differently, keeping the project’s text; see Edit source text in Hyperlocalise. Recent syncs in the Sync settings, or the step’s output in a visual workflow, lists the hidden keys and the clashes per file and counts the files that were not imported: a path that matched no language, a format the sync can’t read, or a second copy of a source file under another language code.

What goes back to GitLab

After the pull, each run writes one language file per source file and target language, named the way the repository already names that language (fr.json stays fr.json; a language with no file yet gets the project’s tag written the repository’s way, such as de-DE.json or de_DE.json), to one branch per sync, rebuilt on the current target each run, and opens a merge request from it or updates the open one. Only approved translations go, and only where they differ from what the repository has: a key with none keeps whatever the repository’s language file had, a language file’s own extra keys (such as plural forms) and settings stay, keys you hid in the editor keep the repository’s text (or the source’s), and keys the repository dropped are never written back. A list with an item that has no translation yet is left as the repository has it, and Recent syncs says so. A Flutter ARB file gets its own language in @@locale. JSON files keep the source file’s nesting and the language file’s indentation. An HTML page is sent whole, once every segment in it is approved; until then Recent syncs says how many language files with some approved text wait. Other formats, and files that can’t be read, are counted as not sent. When nothing changes the merge request is left as it is, and every run links to it; if a translation is taken back out of approval and the merge request still carries it, the run closes that merge request, saying why above whatever its description said. A sent JSON file follows the source file’s key order and JSON escaping, so the first merge request for a file written another way shows that reordering too. A merge request you close stays closed until the translations to send change; one the run closed itself says why in its description and never holds the next one back. Where two source files would name the same language file, or a target language’s file would be the source file itself, neither is sent, and the run says so. If GitLab refuses the write (a token without the api scope, a project rule), the run still succeeds with the pull and says why translations weren’t sent. Make translation fixes in Hyperlocalise rather than in the merge request, which is rebuilt on each run; its title is left alone, so marking it as a draft holds it. With Allow source text editing on, the same merge request also writes the project’s source text into the repository’s JSON, JSONC and ARB source files, wherever it was edited in Hyperlocalise or kept in a clash, so merging it brings the repository in line. Only the edited strings change; the rest of the file stays as it is. Strings hidden in the editor and keys the repository dropped are left as the file has them, and so is a list item that clashes, since an item added above it in the repository may have moved it. Recent syncs counts the source files sent, and the merge request’s description says when it changes source text. A GitHub sync doesn’t write source text back.

Connect the translation step

Content sync itself does not create translation jobs. Add a Source upload automation or request a translation after the source arrives. Review the translations before the next outbound sync. Use a small test file to verify the full sequence: source arrives, translation runs, review completes, and the expected target path appears in a pull request.

Avoid duplicate delivery

Decide whether Platform content sync or your CLI/CI workflow owns a given source-to-target mapping. Running both for the same paths can produce competing updates. Keep the repository branch and locale paths consistent across the chosen workflow. For troubleshooting, distinguish connection access, sync errors, generation errors, and review readiness. See Automation troubleshooting and the GitHub workflow tutorial.