Skip to content

Translating Widgets

On this page

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 a widget shows the wrong language, this page tells you which
of the three it is and where to fix it.

This covers classic widgets – Search, Categories, Recent Posts, Tag Cloud, Custom HTML and the
rest of the widgets you place in Appearance → Widgets, or that a theme/page builder adds under
a “WordPress” or “WordPress Widget” category (Elementor’s wp-widget-* widgets are this: they are
your theme’s own registered widget, only wrapped so it can be dragged onto an Elementor page). A
widget an Elementor add-on built from scratch (not a wrapped WordPress widget) is a different case

  • see Translating Custom Elementor Widgets.

#The three kinds of text

#1. Text you typed into the widget

The Title field every widget has, and the body of a Custom HTML or Text widget, are
content you wrote yourself. WordPress stores it once, the same for every language, so it has to be
translated like any other text on the site.

Turn this on under LATW Multilingual → Settings → Translation → Other objects, with
Classic widgets (title & text fields). Once it is on, each widget instance appears on the
Strings page (filter Type by Widgets), and its fields open in the usual translation
panel from there.

Translating a widget’s title/text by hand is part of the free version. Translating it
automatically with AI requires PRO.

If you leave the Title field empty, WordPress does not store a title at all – the widget falls
back to its own built-in heading, which is case 2 below.

#2. The widget’s own built-in text

A Search widget’s button, a Categories widget’s default heading (“Categories”) when you
left Title empty, a Tag Cloud widget’s heading (“Tags”), a Recent Posts widget’s
default heading (“Recent Posts”) – none of this is stored anywhere in your database. It is a
string built into WordPress core (or, for a theme-specific widget such as a theme’s own
“Recent Posts” variant, built into the theme’s code), printed fresh every time the widget renders.

There is nothing to configure here. This plugin switches WordPress’s own active language for
every visitor to the language of the page they are looking at, and WordPress prints these built-in
strings in whatever language is active – the same mechanism that translates the “Read more” link
or the comment form’s labels. As long as:

  • the target language has a WordPress language pack installed (Settings → General → Site
    Language
    shows the full list WordPress knows; a language with no pack falls back to the
    strings baked into the code, normally English), and
  • the widget’s code actually uses WordPress’s translation functions (__(), _e()) instead of a
    hard-coded string,

the heading changes language on its own, with no setup and no cost, exactly as it does when a
human visitor changes their own WordPress admin language.

When this does not apply: a theme or add-on that typed its own text straight into the PHP code
instead of running it through __()/_e() cannot be switched this way – there is no mechanism to
hook into, because WordPress never sees the string as translatable. That is a limitation of that
widget’s code, not something this plugin (or any translation plugin) can patch from the outside.
If one specific widget’s built-in heading refuses to change language while every other one does,
that is the most likely reason – worth checking with whoever built the theme or add-on.

#3. Content the widget pulls in live

A Recent Posts widget’s list of titles and dates, a Categories widget’s list of category
names and links, a Tag Cloud widget’s list of tags – none of this text lives on the widget
either. It is read fresh, on every page load, from your posts, categories and tags.

There is nothing to configure here either. These widgets automatically show the posts, terms
and links of the language being viewed, because the posts and terms themselves are translated
posts and terms – the same translation you already did (or will do) from the Posts page or the
taxonomy screens. Translate the post, or the category name, and every widget that lists it follows
along; there is no separate “widget content” to keep in sync.

#Quick way to tell them apart

What you see wrong Where to fix it
A title you typed yourself into the widget Strings page, type Widgets (needs the “Classic widgets” setting above)
A heading with no Title set (e.g. widget just says “Categories”) Nothing to fix here – check the target language has a WordPress language pack, and see “When this does not apply” above
A post title, date, category name or tag shown inside the widget Translate that post/category/tag itself
Text typed into an Elementor widget’s own settings (a heading, a button label built by the add-on) See Translating Custom Elementor Widgets

#What this does not do

  • A different set of widgets per language. A sidebar has one set of widgets, shared by every
    language, the same way a menu has one structure. You cannot show a widget in one language only.
  • Widgets whose text lives entirely in unstructured HTML/JS (a raw script embedded in a Custom
    HTML widget, for instance) – only the fields listed in the field map above are read; arbitrary
    markup inside them is left as-is.
  • Block-based widgets you built with the block editor’s own text blocks (Paragraph, Heading,
    etc., inside a “block” widget) are translated too, but as block content – see the block editor’s
    own strings under Strings → Blocks rather than the Widgets filter.

#Developer reference

The classic-widget field map (which fields of which id_base are treated as text) is
array( 'title' => 'text', ... ) per widget type, filterable with latwm_widget_text_fields:

add_filter( 'latwm_widget_text_fields', function ( $map ) {
    // A theme widget registered as id_base "tj-recent-posts" with its own "title" setting.
    $map['tj-recent-posts'] = array( 'title' => 'text' );
    return $map;
} );

A widget id_base not in this map is not offered on the Strings page at all – its Title field
(if it stores one) stays untranslated even with Classic widgets turned on, until it is added
here. This only affects case 1 above (text you typed); cases 2 and 3 are unaffected by this map,
since they do not go through the widget-translation layer at all.