{"id":334939,"date":"2026-07-02T20:44:27","date_gmt":"2026-07-02T20:44:27","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/sawir-live-translate\/"},"modified":"2026-07-02T20:44:15","modified_gmt":"2026-07-02T20:44:15","slug":"sawir-live-translate","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/sawir-live-translate\/","author":18200539,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.0","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"Sawir Live Translate","header_author":"Ricardo Sawir","header_description":"Open any front-end page in an editor, pick a target language, auto-translate the visible strings, and save them so visitors can switch languages.","assets_banners_color":"","last_updated":"2026-07-02 20:44:15","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/sawirstudio.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":35,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"sawirricardo","date":"2026-07-02 20:44:15"}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[1734,99,2333],"plugin_category":[48],"plugin_contributors":[262686],"plugin_business_model":[],"class_list":["post-334939","plugin","type-plugin","status-publish","hentry","plugin_tags-localization","plugin_tags-multilingual","plugin_tags-translation","plugin_category-language-tools","plugin_contributors-sawirricardo","plugin_committers-sawirricardo"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/sawir-live-translate.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Open any page on your site, click \"Translate this page\" in the admin bar, choose a\ntarget language, and either auto-translate every visible string (via a free\nmachine-translation service) or edit translations by hand while seeing the page\nupdate live.<\/p>\n\n<p>Saved translations are rendered server-side into the HTML response (SEO-friendly:\nno flash of untranslated text, and hreflang alternates in the head), and visitors\nswitch languages via a link-based switcher (bottom-right).<\/p>\n\n<p>Developed by Ricardo Sawir for Sawir Studio LLC.<\/p>\n\n<ul>\n<li>Website: https:\/\/sawirstudio.com<\/li>\n<li>X: https:\/\/x.com\/RicardoSawir<\/li>\n<li>GitHub: https:\/\/github.com\/sawirricardo<\/li>\n<li>Email: ricardo@sawirstudio.com<\/li>\n<\/ul>\n\n<p>URLs use a language path prefix, e.g. \/es\/about for Spanish, \/about for the source\nlanguage (which stays canonical, un-prefixed). Language is resolved in this order:\n\/es\/ path \u2192 ?lang=es \u2192 saved cookie \u2192 browser Accept-Language \u2192 source. Root and\nprefix-less URLs auto-detect the visitor's browser language without redirecting\n(a Vary header is sent so shared caches behave).<\/p>\n\n<ol>\n<li>Settings \u2192 Live Translate: set your source language and tick the languages to offer.<\/li>\n<li>Visit a front-end page and click \"\ud83c\udf10 Translate this page\" in the admin bar.<\/li>\n<li>Pick a language, hit \"Auto-translate empty\" (or edit strings), then \"Save\".<\/li>\n<li>Visitors use the switcher (bottom-right); each language has its own \/xx\/ URL.<\/li>\n<\/ol>\n\n<p>Note: language path prefixes assume a root-domain install and no top-level page\nwhose slug is a two-letter language code.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin's optional \"Auto-translate\" feature (admin-only, triggered manually\nby clicking an Auto-translate\/Translate button) sends the source text strings\nand the chosen language pair to the MyMemory translation API\n(https:\/\/mymemory.translated.net\/) to fetch machine translations. The request\nis made from the administrator's browser only when they click the button; no\nvisitor data is ever sent, and nothing is sent automatically.<\/p>\n\n<ul>\n<li>Service terms: https:\/\/mymemory.translated.net\/doc\/en\/tos.php<\/li>\n<li>Privacy policy: https:\/\/mymemory.translated.net\/doc\/en\/privacy.php<\/li>\n<\/ul>\n\n<p>Developers can swap the provider \u2014 see \"Custom translation provider\" below.<\/p>\n\n<h3>Native WordPress localization (dates, core\/theme strings)<\/h3>\n\n<p>On a translated request the plugin switches WordPress's locale to the target\nlanguage, so dates (month\/day names) and any <em>installed<\/em> core, theme, and plugin\ntranslations render natively \u2014 the string map only covers the rest.<\/p>\n\n<p>For this to have visible effect the language pack must be installed. The easiest\nway is Settings \u2192 General \u2192 Site Language: pick and save the language once (which\ndownloads its pack), then switch back to your source language. Languages without\nan installed pack still work for content translation; only native dates\/strings\nare skipped. Map codes to custom WP locales with the 'sawir_lt_wp_locale' filter.<\/p>\n\n<h3>Scan site for strings<\/h3>\n\n<p>Settings \u2192 Live Translate \u2192 \"Scan site now\" crawls your published pages, posts,\nand public archives to discover every translatable string up front (batched, with\na progress indicator). Discovered strings then appear in the \"Edit all site\nstrings\" section right below, where you can pick a language and translate, auto-\ntranslate, or bulk-import the whole site at once instead of page by page. Note:\nmachine translation is still rate-limited by the free service, so for large sites\nuse Bulk edit to export and translate elsewhere.<\/p>\n\n<h3>Multisite<\/h3>\n\n<p>Multisite-aware. Each subsite has its own settings and its own translations table,\nconfigured independently. Tables are created on network activation, when a new\nsubsite is created, and lazily on first admin visit; uninstall cleans every site\non the network.<\/p>\n\n<h3>Custom switcher<\/h3>\n\n<p>Turn off \"Built-in switcher\" in settings and render your own anywhere in your\ntheme using sawir_lt_switcher_links(), which returns the language links for the\ncurrent page:<\/p>\n\n<pre><code>&lt;?php if ( function_exists( 'sawir_lt_switcher_links' ) ) : ?&gt;\n  &lt;ul class=\"my-lang-switcher\"&gt;\n  &lt;?php foreach ( sawir_lt_switcher_links() as $l ) : ?&gt;\n    &lt;li&gt;\n      &lt;a href=\"&lt;?php echo esc_url( $l['url'] ); ?&gt;\"&lt;?php echo $l['active'] ? ' aria-current=\"true\"' : ''; ?&gt;&gt;\n        &lt;?php echo esc_html( $l['name'] ); ?&gt;\n      &lt;\/a&gt;\n    &lt;\/li&gt;\n  &lt;?php endforeach; ?&gt;\n  &lt;\/ul&gt;\n&lt;?php endif; ?&gt;\n<\/code><\/pre>\n\n<p>Each item is ['code','name','url','active','is_source'] (code is '' for the\nsource language). sawir_lt_current_lang() returns the active language code.<\/p>\n\n<h3>Custom translation provider<\/h3>\n\n<p>Auto-translate uses the free MyMemory API by default. To use your own provider\n(DeepL, Google, a local model, ...), reassign window.SawirLT.translate from a\nscript enqueued after the 'sawir-lt-walk' handle. Signature: it receives the\nsource text and the two language codes, and returns a Promise resolving to the\ntranslated string. Every auto-translate path (in-page editor and admin bulk\ntranslate) routes through it.<\/p>\n\n<pre><code>add_action( 'admin_enqueue_scripts', 'myprefix_lt_provider' );\nadd_action( 'wp_enqueue_scripts', 'myprefix_lt_provider' );\nfunction myprefix_lt_provider() {\n    if ( wp_script_is( 'sawir-lt-walk', 'registered' ) ) {\n        wp_enqueue_script( 'myprefix-lt-provider',\n            plugins_url( 'provider.js', __FILE__ ),\n            array( 'sawir-lt-walk' ), '1.0.0', true );\n    }\n}\n<\/code><\/pre>\n\n<p>provider.js:<\/p>\n\n<pre><code>window.SawirLT.translate = function ( text, source, target ) {\n    return fetch( 'https:\/\/example.com\/translate', {\n        method: 'POST',\n        body: JSON.stringify( { text: text, from: source, to: target } )\n    } ).then( function ( r ) { return r.json(); } )\n      .then( function ( j ) { return j.translation; } );\n};&lt;h3&gt;Translations&lt;\/h3&gt;\n<\/code><\/pre>\n\n<p>The plugin's own admin\/UI text is translation-ready (text domain\n\"sawir-live-translate\"). A .pot template ships in \/languages \u2014 drop your\n.po\/.mo there or under wp-content\/languages\/plugins\/. (The in-page editor's\nJavaScript labels are not yet localized.)<\/p>\n\n<h3>Other plugins by Sawir Studio<\/h3>\n\n<ul>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-restock-notifier-for-woocommerce\/\">Sawir Restock Notifier for WooCommerce<\/a> \u2014 let customers request an email when an out-of-stock product is back.<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-product-image-zoom-for-woocommerce\/\">Sawir Product Image Zoom for WooCommerce<\/a> \u2014 product image lightbox with navigation and click-to-zoom.<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-variation-gallery-tools-woocommerce\/\">Sawir Variation Gallery Tools for WooCommerce<\/a> \u2014 manage variation-specific gallery images.<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-role-capabilities-manager\/\">Sawir Role Capabilities Manager<\/a> \u2014 create custom user roles and manage capabilities.<\/li>\n<\/ul>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Translate any front-end page live: pick a language, auto-translate the visible strings, save them, and let visitors switch languages.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/334939","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=334939"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/sawirricardo"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=334939"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=334939"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=334939"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=334939"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=334939"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=334939"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}