{"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-08T09:34:55","modified_gmt":"2026-07-08T09:34:55","slug":"sawir-live-translate","status":"publish","type":"plugin","link":"https:\/\/test.wordpress.org\/plugins\/sawir-live-translate\/","author":18200539,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.1.0","stable_tag":"1.1.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-08 09:34:55","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":121,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"sawirricardo","date":"2026-07-02 20:44:15"},"1.0.1":{"tag":"1.0.1","author":"sawirricardo","date":"2026-07-06 14:00:07"},"1.1.0":{"tag":"1.1.0","author":"sawirricardo","date":"2026-07-08 09:34:55"}},"upgrade_notice":[],"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.0.1","1.1.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<li><a href=\"https:\/\/wordpress.org\/plugins\/sawir-media-folders\/\">Sawir Media Folders<\/a> \u2014 organize the Media Library into fast, unlimited folders with drag &amp; drop.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate the plugin, then go to Settings \u2192 Live Translate.<\/li>\n<li>Set your <strong>Source language<\/strong> \u2014 the language your site is written in.<\/li>\n<li>Tick every <strong>Target language<\/strong> you want to offer visitors, adjust the\nswitcher style if you like, and click Save.<\/li>\n<\/ol>\n\n<p>Optional: for translated dates and built-in theme text to switch too, install\nthe language pack once via Settings \u2192 General \u2192 Site Language (pick the\nlanguage, save, then switch back). Content translation works without it.<\/p>\n\n<h4>Translate a page<\/h4>\n\n<ol>\n<li>While logged in, visit any page on the front end and click\n<strong>\ud83c\udf10 Translate this page<\/strong> in the admin bar.<\/li>\n<li>In the panel, pick the target language.<\/li>\n<li>Click <strong>Auto-translate empty<\/strong> \u2014 every visible string is machine-translated\nand the page updates live. You can also type or fix any translation by\nhand; click a source string in the panel to highlight it on the page.<\/li>\n<li><strong>Click Save.<\/strong> Everything before saving is only a preview in your own\nbrowser. Wait for the status line to say \"saved N translations \u2713\".<\/li>\n<li>Verify under Settings \u2192 Live Translate \u2192 Saved translations: your language\nshould be listed with a string count. If it isn't, nothing was saved \u2014 go\nback and Save again.<\/li>\n<\/ol>\n\n<h4>Translate the whole site at once<\/h4>\n\n<ol>\n<li>Settings \u2192 Live Translate \u2192 \"Scan site now\" crawls your published pages and\ncollects every translatable string.<\/li>\n<li>In \"Edit all site strings\" below it, pick a language, click Load strings,\nthen Auto-translate empty (or Bulk edit), and Save.<\/li>\n<\/ol>\n\n<p>Auto-translate uses a free service with a daily limit. If it stops with a\n\"limit reached\" message your progress is kept \u2014 Save, and continue later. Or\nuse Bulk edit to copy all strings as JSON, translate them anywhere (a paid\nservice, AI, a human translator), paste back, Apply, and Save.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"i%20switch%20languages%20but%20nothing%20changes\"><h3>I switch languages but nothing changes<\/h3><\/dt>\n<dd><p>Almost always this means no translations are saved for that language yet.\nCheck Settings \u2192 Live Translate \u2192 Saved translations \u2014 if the language isn't\nlisted (or shows 0 strings), open the page editor again, auto-translate, and\nclick Save. The live preview in the editor is not saved until you do.<\/p><\/dd>\n<dt id=\"some%20strings%20stay%20untranslated\"><h3>Some strings stay untranslated<\/h3><\/dt>\n<dd><p>The in-page editor only sees strings on the page you opened. Text that lives\non other pages needs those pages translated too \u2014 or run the site-wide scan.\nStrings injected by sliders\/scripts after page load may need a manual entry\nvia \"Edit all site strings\".<\/p><\/dd>\n<dt id=\"i%20edited%20my%20content%20and%20its%20translation%20disappeared\"><h3>I edited my content and its translation disappeared<\/h3><\/dt>\n<dd><p>Translations are matched to the exact original text. If you rewrite a\nsentence, translate the new version once and save.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20caching%20plugins%3F\"><h3>Does it work with caching plugins?<\/h3><\/dt>\n<dd><p>LiteSpeed Cache is supported out of the box (pages are varied per language\ncookie). For other page caches, exclude or vary on the sawir_lt_lang cookie,\nand purge the cache after saving translations.<\/p><\/dd>\n<dt id=\"can%20i%20hide%20the%20floating%20switcher%20and%20use%20my%20own%3F\"><h3>Can I hide the floating switcher and use my own?<\/h3><\/dt>\n<dd><p>Yes \u2014 untick \"Show the built-in language switcher\" in settings and render\nyour own with sawir_lt_switcher_links(); see \"Custom switcher\" below.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Fix: language switching could get stuck on one language behind LiteSpeed Cache \u2014 cached pages are now varied per language cookie (X-LiteSpeed-Vary header + litespeed_vary_cookies filter).<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Add links to other Sawir Studio plugins.<\/li>\n<\/ul>\n\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:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/334939","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=334939"}],"author":[{"embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/sawirricardo"}],"wp:attachment":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=334939"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=334939"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=334939"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=334939"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=334939"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=334939"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}