{"id":122,"date":"2026-09-25T06:56:40","date_gmt":"2026-09-25T06:56:40","guid":{"rendered":"https:\/\/docs.latw.ai\/uncategorized\/translating-widgets\/"},"modified":"2026-09-25T06:56:40","modified_gmt":"2026-09-25T06:56:40","slug":"translating-widgets","status":"publish","type":"post","link":"https:\/\/docs.latw.ai\/pl\/latw-multilingual\/translating-widgets\/","title":{"rendered":"Translating Widgets"},"content":{"rendered":"<p>A widget on your site shows up to three different kinds of text, and each one is translated by a<br \/>\ndifferent part of the plugin. When a widget shows the wrong language, this page tells you which<br \/>\nof the three it is and where to fix it.<\/p>\n<p>This covers <strong>classic widgets<\/strong> &#8211; Search, Categories, Recent Posts, Tag Cloud, Custom HTML and the<br \/>\nrest of the widgets you place in <strong>Appearance \u2192 Widgets<\/strong>, or that a theme\/page builder adds under<br \/>\na &#8220;WordPress&#8221; or &#8220;WordPress Widget&#8221; category (Elementor&#8217;s <code>wp-widget-*<\/code> widgets are this: they are<br \/>\nyour theme&#8217;s own registered widget, only wrapped so it can be dragged onto an Elementor page). A<br \/>\nwidget an Elementor add-on built from scratch (not a wrapped WordPress widget) is a different case<\/p>\n<ul>\n<li>see <em>Translating Custom Elementor Widgets<\/em>.<\/li>\n<\/ul>\n<h2>The three kinds of text<\/h2>\n<h3>1. Text you typed into the widget<\/h3>\n<p>The <strong>Title<\/strong> field every widget has, and the body of a <strong>Custom HTML<\/strong> or <strong>Text<\/strong> widget, are<br \/>\ncontent you wrote yourself. WordPress stores it once, the same for every language, so it has to be<br \/>\ntranslated like any other text on the site.<\/p>\n<p>Turn this on under <strong>LATW Multilingual \u2192 Settings \u2192 Translation \u2192 Other objects<\/strong>, with<br \/>\n<strong>Classic widgets (title &amp; text fields)<\/strong>. Once it is on, each widget instance appears on the<br \/>\n<strong>Strings<\/strong> page (filter <strong>Type<\/strong> by <strong>Widgets<\/strong>), and its fields open in the usual translation<br \/>\npanel from there.<\/p>\n<p><em>Translating a widget&#8217;s title\/text by hand is part of the free version. Translating it<br \/>\nautomatically with AI requires <strong>PRO<\/strong>.<\/em><\/p>\n<p>If you leave the <strong>Title<\/strong> field empty, WordPress does not store a title at all &#8211; the widget falls<br \/>\nback to its own built-in heading, which is case 2 below.<\/p>\n<h3>2. The widget&#8217;s own built-in text<\/h3>\n<p>A <strong>Search<\/strong> widget&#8217;s button, a <strong>Categories<\/strong> widget&#8217;s default heading (&#8220;Categories&#8221;) when you<br \/>\nleft <strong>Title<\/strong> empty, a <strong>Tag Cloud<\/strong> widget&#8217;s heading (&#8220;Tags&#8221;), a <strong>Recent Posts<\/strong> widget&#8217;s<br \/>\ndefault heading (&#8220;Recent Posts&#8221;) &#8211; none of this is stored anywhere in your database. It is a<br \/>\nstring built into WordPress core (or, for a theme-specific widget such as a theme&#8217;s own<br \/>\n&#8220;Recent Posts&#8221; variant, built into the theme&#8217;s code), printed fresh every time the widget renders.<\/p>\n<p><strong>There is nothing to configure here.<\/strong> This plugin switches WordPress&#8217;s own active language for<br \/>\nevery visitor to the language of the page they are looking at, and WordPress prints these built-in<br \/>\nstrings in whatever language is active &#8211; the same mechanism that translates the &#8220;Read more&#8221; link<br \/>\nor the comment form&#8217;s labels. As long as:<\/p>\n<ul>\n<li>the target language has a WordPress language pack installed (<strong>Settings \u2192 General \u2192 Site<br \/>\nLanguage<\/strong> shows the full list WordPress knows; a language with no pack falls back to the<br \/>\nstrings baked into the code, normally English), and<\/li>\n<li>the widget&#8217;s code actually uses WordPress&#8217;s translation functions (<code>__()<\/code>, <code>_e()<\/code>) instead of a<br \/>\nhard-coded string,<\/li>\n<\/ul>\n<p>the heading changes language on its own, with no setup and no cost, exactly as it does when a<br \/>\nhuman visitor changes their own WordPress admin language.<\/p>\n<p><strong>When this does not apply:<\/strong> a theme or add-on that typed its own text straight into the PHP code<br \/>\ninstead of running it through <code>__()<\/code>\/<code>_e()<\/code> cannot be switched this way &#8211; there is no mechanism to<br \/>\nhook into, because WordPress never sees the string as translatable. That is a limitation of that<br \/>\nwidget&#8217;s code, not something this plugin (or any translation plugin) can patch from the outside.<br \/>\nIf one specific widget&#8217;s built-in heading refuses to change language while every other one does,<br \/>\nthat is the most likely reason &#8211; worth checking with whoever built the theme or add-on.<\/p>\n<h3>3. Content the widget pulls in live<\/h3>\n<p>A <strong>Recent Posts<\/strong> widget&#8217;s list of titles and dates, a <strong>Categories<\/strong> widget&#8217;s list of category<br \/>\nnames and links, a <strong>Tag Cloud<\/strong> widget&#8217;s list of tags &#8211; none of this text lives on the widget<br \/>\neither. It is read fresh, on every page load, from your posts, categories and tags.<\/p>\n<p><strong>There is nothing to configure here either.<\/strong> These widgets automatically show the posts, terms<br \/>\nand links of the language being viewed, because the posts and terms themselves are translated<br \/>\nposts and terms &#8211; the same translation you already did (or will do) from the <strong>Posts<\/strong> page or the<br \/>\ntaxonomy screens. Translate the post, or the category name, and every widget that lists it follows<br \/>\nalong; there is no separate &#8220;widget content&#8221; to keep in sync.<\/p>\n<h2>Quick way to tell them apart<\/h2>\n<table>\n<thead>\n<tr>\n<th>What you see wrong<\/th>\n<th>Where to fix it<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>A title you typed yourself into the widget<\/td>\n<td><strong>Strings<\/strong> page, type <strong>Widgets<\/strong> (needs the &#8220;Classic widgets&#8221; setting above)<\/td>\n<\/tr>\n<tr>\n<td>A heading with no <strong>Title<\/strong> set (e.g. widget just says &#8220;Categories&#8221;)<\/td>\n<td>Nothing to fix here &#8211; check the target language has a WordPress language pack, and see &#8220;When this does not apply&#8221; above<\/td>\n<\/tr>\n<tr>\n<td>A post title, date, category name or tag shown <em>inside<\/em> the widget<\/td>\n<td>Translate that post\/category\/tag itself<\/td>\n<\/tr>\n<tr>\n<td>Text typed into an Elementor widget&#8217;s own settings (a heading, a button label built by the add-on)<\/td>\n<td>See <em>Translating Custom Elementor Widgets<\/em><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>What this does not do<\/h2>\n<ul>\n<li><strong>A different set of widgets per language.<\/strong> A sidebar has one set of widgets, shared by every<br \/>\nlanguage, the same way a menu has one structure. You cannot show a widget in one language only.<\/li>\n<li><strong>Widgets whose text lives entirely in unstructured HTML\/JS<\/strong> (a raw script embedded in a Custom<br \/>\nHTML widget, for instance) &#8211; only the fields listed in the field map above are read; arbitrary<br \/>\nmarkup inside them is left as-is.<\/li>\n<li><strong>Block-based widgets you built with the block editor&#8217;s own text blocks<\/strong> (Paragraph, Heading,<br \/>\netc., inside a &#8220;block&#8221; widget) are translated too, but as block content &#8211; see the block editor&#8217;s<br \/>\nown strings under <strong>Strings \u2192 Blocks<\/strong> rather than the Widgets filter.<\/li>\n<\/ul>\n<h2>Developer reference<\/h2>\n<p>The classic-widget field map (which fields of which <code>id_base<\/code> are treated as text) is<br \/>\n<code>array( 'title' =&gt; 'text', ... )<\/code> per widget type, filterable with <code>latwm_widget_text_fields<\/code>:<\/p>\n<pre><code class=\"language-php\">add_filter( 'latwm_widget_text_fields', function ( $map ) {\n    \/\/ A theme widget registered as id_base \"tj-recent-posts\" with its own \"title\" setting.\n    $map['tj-recent-posts'] = array( 'title' =&gt; 'text' );\n    return $map;\n} );<\/code><\/pre>\n<p>A widget id_base not in this map is not offered on the Strings page at all &#8211; its <strong>Title<\/strong> field<br \/>\n(if it stores one) stays untranslated even with <strong>Classic widgets<\/strong> turned on, until it is added<br \/>\nhere. This only affects case 1 above (text you typed); cases 2 and 3 are unaffected by this map,<br \/>\nsince they do not go through the widget-translation layer at all.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A widget on your site shows up to three different kinds of text, and each one is translated by a different part of the plugin. When\u2026<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_latwm_translated_slug":"","footnotes":""},"categories":[4],"tags":[],"class_list":["post-122","post","type-post","status-publish","format-standard","hentry","category-latw-multilingual"],"_links":{"self":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/posts\/122","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/comments?post=122"}],"version-history":[{"count":0,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/posts\/122\/revisions"}],"wp:attachment":[{"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/media?parent=122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/categories?post=122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/docs.latw.ai\/pl\/wp-json\/wp\/v2\/tags?post=122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}