Configure Weblate's Git Push Hook to Push Approved Translations
Enable Weblate's built-in Push hook so approved translations are automatically committed and pushed to your upstream Git repository.
18 Jun 2026, 13:23 UTC

Problem and useful takeaway
When a translator approves a string in Weblate, the change is saved to Weblate's internal version-control checkout. It does not automatically appear in the upstream repository that your build system or application consumes. Teams often discover missing translations only after a release, because someone forgot to run a manual push.
This guide shows how to enable Weblate's built-in Push hook so that approved translations are committed and pushed to the upstream Git repository without manual intervention. It covers prerequisites, the admin configuration, a test procedure, and what to check when a push fails.
Prerequisites and version assumptions
This procedure assumes Weblate 4.5 or later. The Push hook is a component-level setting, so you need:
- Weblate administrator access to the component you want to configure.
- A Git repository component already created in Weblate, connected to the upstream repository you want to receive translations.
- Write permission to that upstream repository, using either an SSH private key registered with Weblate or an HTTP authentication token.
- Synchronized system time on the Weblate server. Time drift can delay or skip scheduled hook execution.
Weblate stores translations in PO/MO files. PO files are human-readable localization source files; MO files are compiled binary versions used by some applications at runtime.
Enable the Push hook
- Open the Weblate admin interface and navigate to Components, then select your component.
- Open the Hooks tab for that component.
- Find the Push hook and enable it.
- Set the push URL to the upstream repository endpoint, for example an SSH URL such as
[contact removed]:ORGANIZATION/REPOSITORY.gitor an HTTPS URL. - Choose the authentication method. If you use SSH, install the corresponding private key in Weblate's server settings or component credentials before saving. If you use HTTPS, provide a token with repository write scope; avoid embedding a password in the URL.
- Select the target branch, such as
mainormaster. - Optionally configure the push frequency. Weblate can push on translation events or on a schedule; leaving it event-driven is usually sufficient for low-to-moderate translation volume.
- Save the hook.
Example configuration
Suppose your component slug is website-locale and your upstream repository is at [contact removed]:example-org/website-locale.git. In the Push hook form you would enter:
- Push URL:
[contact removed]:example-org/website-locale.git - Branch:
main - Authentication: SSH key already uploaded to Weblate and authorized on the GitHub repository as a deploy key.
Replace example-org and website-locale with your actual organization and repository names. Do not use a personal access token with full account scope when a repository-scoped deploy key or token is sufficient.
Run a test push and verify
After saving, trigger a test from the same Hooks page using the Run hook or Push repository button, depending on your Weblate version. Required permissions: Weblate administrator for the component.
Expected checks:
- Weblate displays a success message after the test push.
- The component's Activity log shows a push-hook execution entry.
- The upstream repository contains a new commit with updated PO files for the languages you modified.
- No new commit appears when no translation strings have changed since the last push.
To verify end-to-end, make a small translation change in Weblate, approve it, wait for the hook to run, then inspect the upstream repository commit history. If the commit does not appear within a few minutes, check the Weblate logs under Administration → Logs.
Diagnose push failures
When a push fails, Weblate records the error in the admin log. Common causes and checks:
| Symptom | Likely cause | Check |
|---|---|---|
| Authentication failed | SSH key missing, wrong passphrase, or revoked token | Verify the key is installed on the Weblate server and accepted by the upstream host; test the token with a manual Git command. |
| Repository not found | Incorrect push URL or missing read access | Confirm the URL spelling and that the Weblate service account can clone the repository. |
| No changes to push | No approved translations since last push | Expected behavior; no action required. |
| Hook did not run | Time drift or disabled hook | Check server time with date and confirm the Push hook is enabled in the component settings. |
Run commands on the Weblate server, not your local workstation, and use the user account that runs the Weblate service. If you test Git access manually, use a temporary clone directory and remove it afterward to avoid leaving credentials on disk.
As an immediate recovery step, use the Push repository button in the component admin to push manually, or temporarily disable the Push hook while you correct credentials. Re-enable it only after a manual push succeeds.
Limitations and rollback
The Push hook only pushes when Weblate detects uncommitted translation changes. It does not merge conflicting upstream changes automatically; if someone pushes directly to the same branch, Weblate's next push may fail until the local checkout is rebased or merged.
Because enabling or disabling the hook changes component state, you can roll back by returning to Components → your component → Hooks and setting the Push hook to disabled. This stops automatic pushes without removing existing translation data.
Practical verification after rollback: approve a test translation and confirm that no new commit appears in the upstream repository.
Final verification checklist
- Push hook is enabled on the correct component.
- Push URL and branch match the upstream repository.
- Authentication uses SSH or a scoped token, not a plaintext password.
- Test push produced an activity-log entry and an upstream commit.
- Weblate server time is synchronized.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.