Simple Post Translator
Auto-translates published posts into admin-selected languages using the Google Translate API. Adds a language dropdown to posts.
by Pavel Kocev · github.com/pkocev49/simple-post-translator-custom-wordpress-plugin
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/pkocev49/simple-post-translator-custom-wordpress-plugin/archive/refs/heads/main.zipReadme
Simple Post Translator
Translates published WordPress posts into other languages using the Google Cloud Translation API, and adds a language dropdown to the post.
Posts are written in English. When you publish (or update) a post, the plugin sends it to Google once per enabled language and stores the result in postmeta. Nothing is translated at page load, so visitors never wait on an API call and you never pay twice for the same post.
Setup
- Get a Google Cloud Translation API key (console.cloud.google.com → enable Cloud Translation API → Credentials → Create Credentials → API key). Billing has to be enabled on the project even for the free tier.
- Drop the plugin folder in
wp-content/plugins/and activate it. - Go to Settings → Post Translator, paste the key, tick the languages you want, save.
- Publish a short test post and check
wp-content/debug.logif nothing shows up.
Showing the switcher
The dropdown is added above the post content automatically via a the_content filter.
If you want it somewhere else instead, there's a shortcode:
[spt_language_switcher]
Or call it directly from a template:
<?php echo spt_render_language_dropdown(); ?>
Note that on a block theme there is no single.php to edit — use the Site Editor and a shortcode block, or leave the filter alone and let it handle placement.
How it stores things
Translations live in postmeta, one row per language:
_spt_translation_mk
_spt_translation_sr
Each holds an array with title, content, and source_hash. The hash is the md5 of the original title + content, so you can tell whether a stored translation is stale relative to the post it came from.
Language is selected with a query param — /some-post/?spt_lang=mk. English is the default and needs no param.
Gotchas
Existing posts don't get translated. The hooks only fire on publish and on update, so anything published before you installed this stays English until you edit and re-save it.
IPv6 will get you a 403. If you IP-restrict the API key, the server may call out over IPv6 while you whitelisted an IPv4 address. There's an http_api_curl hook in translator.php that forces IPv4 for Google calls. On shared hosting the outbound IP can change when the host migrates you, and translations then fail silently — the error goes to debug.log and the post falls back to English, so nothing looks broken on the front end.
Character count includes HTML. Requests use format=html to keep markup intact, which means all the Gutenberg comment markup counts toward your quota. A post that reads as 800 words can easily bill 6,000+ characters, multiplied by the number of target languages. The free tier is 500,000 characters a month.
No hreflang tags. Search engines have no idea the translated versions exist. If that matters, they need to be added.
Query param URLs, not clean ones. ?spt_lang=mk rather than /mk/some-post/. Fine for a small site, worse for SEO than a real multilingual setup like Polylang.
Files
simple-post-translator.php plugin header, constants, includes
includes/settings.php settings page (API key, language checkboxes)
includes/translator.php publish/update hooks, Google API call
includes/frontend.php dropdown, content and title swap
Debugging
Turn on logging in wp-config.php:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
Then watch it while you republish a post:
tail -f wp-content/debug.log
Failed API calls are logged with the full response body, which is usually enough to see what Google is complaining about.