= 1.7.7 =
* Fixed: content loaded after the page (AJAX) on a translated page kept its scripts and styles whole. A script holding HTML in a string — like SupportCandy's ticket form — came back cut in half, and its «Submit» button did nothing.
* Fixed: links in content loaded by AJAX (a portfolio's next page, «load more») now stay in the visitor's language even when none of its texts is translated yet — «Read more» used to lead back to the default language.

= 1.7.6 =
* New: Switcher → «Your site, live» — with the languages in your header menu (or in a spot you chose) the Switcher screen shows your real header, drawn with the settings on the page before you save, on desktop and phone.
* New: put the languages right after any item of your header menu (Switcher → Where in the menu → «Right after:»), not only at its start or end. Classic menus and the Navigation block of block themes.
* New: a profile such as «header» can be the one in the header menu: choose «In my header menu» in that profile and the menu shows its style. One profile at a time.
* Fixed: the colours of the switcher (text, hover, dropdown background, border, corners) now apply to the languages in your header menu too — they used to be ignored there.
* New: the row of languages at the bottom of the page can be aligned left, centre or right, and shown as a table of 2, 3 or 4 columns (2 on phones); it takes the switcher's text colours. «Your site, live» shows the bottom of the page too.
* Fixed: «Your site, live» shows only the languages your visitors see (not the ones still offline).

= 1.7.5 =
* Fixed: «Translate in this browser» (no API key) now saves sentences that have a link or bold words inside. They used to come back without their link marks and stayed untranslated; now the marks are kept, and where the browser's translator drops them the sentence is translated piece by piece around its links.
* Fixed: a phrase the browser's translator refuses is tried once, not again and again — the run could go round without end and the counter passed the total («Translating 162 of 154»).
* New: «Translate in this browser» also on the screen of a single page (Translations → a page), for that page's strings only.
* Fixed: the same link-safe translation in the visual editor's «Translate in this browser».
* Fixed: in block themes (Navigation block) the languages in your header menu now show their flags, and open on click when the switcher is set to open on click — the rest of your menu keeps opening as before.
* Clearer: a switcher profile other than Default says that the header menu, the spot on your page, the floating switcher and the bottom row all use the Default profile.

= 1.7.4 =
* New: the language switcher in your theme's header menu — Switcher → «In my header menu». The languages become a real item of the menu, drawn by your theme like its other items, with its submenu and its phone menu: classic themes (Astra, GeneratePress, Kadence, OceanWP…), Elementor's Nav Menu, and block themes through the Navigation block. At the start or at the end of the menu. Where a page has no such menu, the switcher floats in the corner, so it is never missing. The setup wizard offers it when the theme has a menu.
* New: if your switcher floats in a corner, TranslateRocket offers once to move it into your header menu — one click, and you see it on your site.
* New: put the switcher exactly where you want — Switcher → «In a spot I choose on my page» opens your home page with the header, menu, footer and sidebar outlined; click a spot, choose its start or its end, and the real switcher shows there at once. Where the spot is missing or hidden (another page, the desktop menu on a phone) the switcher floats instead.
* New: a row of languages at the bottom of every page, in a line or as a table, and a «Grid» layout for the switcher block and shortcode: flags and names in as many columns as fit.
* New: 40 more languages, 77 in all — among them Catalan, Serbian, Basque, Galician, Lithuanian, Latvian, Estonian, Albanian, Macedonian, Bosnian, Georgian, Armenian, Azerbaijani, Kazakh, Urdu, Tamil, Telugu, Marathi, Gujarati, Punjabi, Nepali, Sinhala, Swahili, Afrikaans, Filipino, Icelandic, Irish, Welsh, Maltese, Belarusian, Mongolian, Khmer, Burmese, Amharic, Uzbek, Luxembourgish, Esperanto, Mexican Spanish, Canadian French and Swiss German — each with its flag, its own address and the WordPress language pack for the interface. A site written in one of them can now pick it as its own language.
* Fix: DeepL received Traditional Chinese as Simplified Chinese, and Norwegian with a code it does not know.
* Fix: on some sites the translated pages lost the theme's design — fonts, colours, the fixed header, footer menus — because a plugin printed an element in the page head (reported with The7, Elementor and the Angie assistant). The attributes of the page body are kept now, whatever another plugin prints.
* Fix: Diagnostics had «Test connection» only for DeepL, OpenAI, Claude, Gemini and Google Translate: Groq, Cloudflare Workers AI and OpenRouter — the free providers the setup wizard recommends — could not be tested there. Every provider with a key is listed now.
* Improved: when a provider refuses a key or answers with an error, «Test connection» says so in a plain sentence in your language («The provider refused this API key…») instead of the provider's technical answer, which stays in the Diagnostics log.
* Fix: saving the settings raised a PHP warning (a leftover from a limit removed long ago); on a site that shows PHP warnings it could break the page shown after saving.
* Fix: plugins that answer on WooCommerce's own AJAX address — FiboSearch's suggestions while a visitor types — answered in the source language on a translated page, and their links led back to the source language. They are translated now and the links keep the page's language (what the visitor typed is never collected). Links to pages of the site inside any AJAX answer keep the page's language too.
* Fix: sentences a plugin or theme writes by hand into the page for its scripts, in a block marked type="text/javascript" — Ultimate FAQ's list of questions suggested while a visitor types in the FAQ search, and many older themes' messages — were skipped and stayed in the source language. Script templates (text/template) are still left alone.
* Fix: on large sites (over 20,000 sentences) the block cart and checkout showed product attributes in the source language («Colour» on an Italian page), and form messages could stay untranslated: both read a group of interface sentences no longer filled since June. They now use the translations of what the cart holds and of the page the form is on.
* Fix: sentences a plugin hands to its scripts with blanks the script fills in — Shortcodes Ultimate's lightbox counter «%curr% of %total%», «Showing %1$s of %2$s» — stayed in the source language where the plugin has no language pack. They are translated now, and a translation is used only if it keeps exactly the same blanks: a counter can never come out broken.
* Fix: Social Chat — the header and footer of the WhatsApp box stayed in the source language: they are a short piece of HTML inside the plugin's settings. Words between paragraphs and headings are now translated; the HTML stays as it is.
* New: text a translated page loads through admin-ajax after it is shown — Ninja Tables rows, many themes' «load more» — becomes translatable, filed under the page that asked for it. Before, it was translated only if the same sentence had been met elsewhere: a table's rows never were. Only public answers are read (never a cart, an account, an order, a signed-in customer's request or anything a visitor sent), and codes a script passes around are left out.
* New: WP Job Manager — the job list on a translated page arrives translated, with the plugin's words in the page's language. It is loaded after the page from an address of its own (/jm-ajax/), which used to answer in the source language whatever page asked. The same holds for LearnPress' and bbPress' own AJAX addresses.
* New: Events Manager — «next month» in the calendar of a translated page shows the events translated. The month is fetched from the page itself and came back with the month name translated and the events in the source language.
* New: structured data for Google — a job's title (JobPosting, read by Google for Jobs) and descriptions written in HTML are translated; the HTML stays as it is. A sentence that holds bold or a link is left whole, never cut into pieces.
* Fix: words a plugin keeps in an attribute whose name runs together — the message Ultimate Blocks' countdown shows when the offer ends, the «This field cannot be blank» and «invalid» errors of Formidable Forms fields — stayed in the source language.
* Fix: once everything was translated, the Translations page still read «14 strings still to translate — 89%» next to a button saying «Everything is translated»: the addresses of the page's images were counted as text to translate. They are not (an image can be swapped per language, if you want), and the count now agrees with the button.
* Improved: a simpler dashboard. The side menu keeps six entries (the other screens are one click away in the buttons at the top), notices from other plugins fold into one line on TranslateRocket's screens, and the Labs box is a single line.
* Improved: with 77 languages, a search box over the language lists (setup wizard and Languages): type a language's own name, its English name or its code. The English name now shows next to the native one — «Српски Serbian».
* Improved: Translations — one main button per page, «Translate»; «Start over» and «Hide» are in a «⋯» menu and still ask before doing anything. A new «Only pages still to translate» filter.
* Improved: AI Translation — the providers you do not use fold to one line; the active one and those in your fallback chain stay open, and choosing a provider opens its card.
* Improved: Switcher — where the switcher goes comes first, then its layout; colours, sizes, font and the phone options are under «More style options».
* Fix: on Windows, Chrome and Edge showed the dashboard's emoji flags as two letters («GB»): the plugin's own flags are used instead.
* Fix: on PHP 7, searching languages or pages by a name in a non-Latin script (Cyrillic, Japanese, Greek…) found nothing.
* Fix: in Dutch, Polish, Russian and Japanese three counters of the dashboard showed in English («3 pages updated.»): their plural forms are in place now.
* Improved: the Translations screen explains <1>…</1> in a visible line where they appear: they mark a link or formatted words, which stay as they are on the site (until now only a tooltip said so).
* Fix: on the Translations and Memory screens, the «Translate with your browser» panel appeared a moment after the page and pushed it down; it is drawn in place now.
* Fix: on the Plugins screen, after the short «why are you leaving?» question, the deactivation page could open twice (the answer and a 4-second safety net both ran it).

= 1.7.3 =
* New: e-mails sent to the visitor by contact forms reach them in the language of the page they wrote from, with their name and answers in place; e-mails to you keep the site's language. Contact Form 7 (the «Mail (2)» automatic reply), WPForms, Fluent Forms, Ninja Forms, Formidable Forms, Everest Forms and SureForms. Their sentences appear in the translation screens under their own heading («Contact Form 7 e-mails», «WPForms e-mails»…); in an HTML message only the text is translated, and a translation that lost one of the [tags] or {tags} is not used for that line.
* New: GiveWP's e-mails to the donor (donation receipt, offline donation instructions) follow the language of the page the donation was made from. Sentences under «GiveWP e-mails».
* New: the message shown once a form is sent (WPForms, Fluent Forms, Ninja Forms, Everest Forms, SureForms, Contact Form 7, Otter Blocks) becomes translatable the first time a visitor sends the form, under «Forms: messages and e-mails», and is then shown in the page's language. Before, it never appeared on a page, so it was never collected. Only the form's own wording is read, never what the visitor typed.
* New: text a translated page loads from the REST API after it is shown — WP Go Maps marker titles and descriptions, and any other content fetched the same way — becomes translatable, filed under the page that asked for it (or under «Content loaded by the page»). Only public answers are read: never a cart, an order, an account, a signed-in customer's request or anything a visitor sent.
* Fix: sentences with a date inside — «Posted on <date>», used by most themes — stayed in the source language on every translated post: WordPress writes the date in the page's language, so the sentence never matched the one collected. A date now keeps its place and only the words around it are translated.
* Fix: GiveWP 3 donation forms (shown in a frame that GiveWP prints without <html>) stayed entirely in the source language on translated pages — title, amounts, labels, payment methods. The form and receipt views are now translated like any page; the `trrocket_translate_frame_view` filter covers similar frames.
* Fix: MetaSlider's arrow labels (and other slider options written as JavaScript rather than JSON: FlexSlider's prevText/nextText, Swiper's accessibility messages) stayed in the source language.
* Fix: sentences WordPress builds around a title — the «Continue reading …» label of the more link, a composed feed title — are translated with the title in them; a post's category in structured data (articleSection) is translated.
* Fix: headings of texts that are not on a page («Forms: messages and e-mails», «WooCommerce emails», the form e-mails…) are shown in the administrator's language; collected while a visitor used a translated page, they could be stored in that page's language.
* Compatibility: Kadence Blocks' icon tooltips and Fluent Forms' payment item labels are translated. Checked with more popular plugins and themes: Chaty, Popup Builder, Otter Blocks, Strong Testimonials, Modula, WP Simple Booking Calendar, and the themes Twenty Twenty-Five, Neve, Sydney, Zakra, Botiga and Hestia.

= 1.7.2 =
* New: a «Plugin language» menu at the top of every TranslateRocket screen. Read the plugin in English, Italian, Spanish, French, German, Portuguese (Brazil), Dutch, Polish, Russian or Japanese whatever your WordPress profile says — each user chooses for themselves, and «Automatic» keeps following the profile. It changes only TranslateRocket's own texts; the tooltip says where to switch the whole dashboard.
* Compatibility: rotating «Fancy Text» phrases are translated phrase by phrase — Essential Addons keeps them in one attribute separated by bars, Premium Addons in the widget's JSON settings — and so are ElementsKit's countdown labels (Days, Hours…) and its Before/After image comparison labels. On/off switches that some blocks keep in attributes named like text (data-show-label="true") are never taken for words to translate. Checked with ten more popular plugins: Easy Table of Contents, Breadcrumb NavXT, AddToAny, Click to Chat (the pre-filled WhatsApp message too), Ally, CookieAdmin, FiboSearch, MC4WP, Essential Addons and ElementsKit.
* Compatibility: words inside the JSON settings that widgets and chat boxes keep in data-* attributes are translated, keys and options untouched — Social Chat's WhatsApp button, Premium Addons' typing text — and Variation Swatches' colour and size tooltips. Plural labels kept in attributes ending in «-plural» are translated too (Qi Addons' countdown shows «Days» from data-day-label-plural).
* Compatibility: MetForm forms (600,000 sites) are translated — labels, placeholders, the button and the error messages. MetForm prints each form as a JavaScript template that the page translation never read; now only its words are replaced and the template works as before.
* Fix: on phones, the language list under «Published, or still being translated?» no longer pushes the ONLINE label out of the table, and the AI provider cards keep their fields, guide and buttons inside the card.

= 1.7.1 =
* New: invoices from PDF Invoices & Packing Slips in the language of the order. An invoice, credit note, proforma or receipt is built in the language the customer ordered in — from the download link, attached to the e-mail or resent from the order screen — and your own footer is translatable under «WooCommerce PDF documents». The customer's details, the invoice number and product codes stay as they are; packing slips stay in the site's language for the warehouse.
* Privacy: the customer's own details — names, company, addresses, e-mail, phone, order note — are no longer collected from WooCommerce e-mails as sentences to translate, nor ever translated. Before, every order e-mail could add them to the list under «WooCommerce emails»: those already there are removed when you update — only details of real orders, seen nowhere but in e-mails, so your shop's own sentences and their translations stay.
* New: a check after every import. The imported translations are reread without AI: broken markup, scripts, a translation identical to the original, changed links or numbers, an odd length or the wrong language are listed on the Import page, to keep or remove one by one or all together.
* Compatibility: the «do not translate» marks of other translation tools are respected — Google's notranslate and skiptranslate classes (GTranslate and many themes), TranslatePress's data-no-translation, Weglot's data-wg-notranslate — so a site that moves here keeps what it had excluded on purpose. On the html or body tag they still only mean «no browser popup».
* Compatibility: text inside open shadow DOMs (cookie banners and widgets built as web components) is read and translated in the browser.
* Compatibility: the social image (og:image, twitter:image) can have a different file per language like any other image; Yoast's «Written by» / «Est. reading time» labels for X (Twitter) are translated; template placeholders such as {{{ data.name }}} or %s alone are never treated as sentences.
* Fix: in the visual editor, its own labels stay in the administrator's language on a translated page.
* For developers: actions trrocket_translation_changed and trrocket_translation_deleted, fired when a translation is saved or deliberately removed (TranslateRocket Labs uses them for its History).
* Tested with: GDPR Cookie Compliance, Say What?, Getwid, Stackable, Visual Portfolio, PDF Invoices & Packing Slips.

= 1.7.0 =
* New: free AI translation with your own free account. Cloudflare Workers AI (10,000 «neurons» a day: about 1,900 sentences with Llama 3.3 70B, or 11,000 with the plain translation model, with a Quality setting — Best, Volume or Automatic), Groq (about 1,000 requests a day with gpt-oss-120b) and OpenRouter's free models are providers like DeepL or OpenAI: in the fallback chain, in bulk translation, in the visual editor. Each has a two-minute guide to get the key, «Load available models» to check it, and today's counter; a little before the free share runs out, the next provider of your chain carries on. Official APIs, no card needed.
* New: the setup wizard offers free AI first. «Free AI, with your own free account»: a Groq key in 2 minutes with a Google account, a «Try the key» button, and the site translates from the first minute — in any browser, phones and Firefox included, where the browser translator does not exist.
* New: the universal importer, on Import. Coming from a translation plugin with no importer here, or one whose tables cannot be read? Keep it on: TranslateRocket reads each page as visitors see it, in every language, finds its translations from the hreflang links, and pairs each sentence with its translation only where the two pages have the same structure — leaving out what changes on every visit and copies, keeping links and bold words. A scan first (nothing saved), then the import, then a side-by-side preview of every page per language while the old plugin still serves your site. Tested on the bench with TranslatePress, Bogo, qTranslate-XT, WPGlobus, WP Multilang, Multilanguage and Polylang, and on pages of 20 real multilingual sites (8 systems): language switchers, cached copies with other content and sentences in the wrong language are left out. It waits while TranslateRocket itself serves the languages, so it never reads its own pages back. Translators that work only in the visitor's browser (GTranslate free, Weglot's JavaScript) cannot be read from the server: the scan says so.
* New: translation style from the kind of site, on AI Translation. A free AI reads your site's name, tagline and main pages and proposes the tone, formal or informal address for each of your languages, and the names never to translate; nothing changes until you press «Use this style». The house style now reaches every AI provider.
* New: a «Sponsor on GitHub» button next to the donation link.
* Improved: German admin screens address you consistently; the Labs page lists what Labs adds for teams.
* Fixed: translations whose source string no longer existed were counted but never shown or exported; they are removed on update.

= 1.5.9 =
* New: the words only a visitor who is not logged in can see — login and registration forms (Ultimate Member, bbPress, WooCommerce «My account»), «You must be logged in to reply», the e-mail field of the review form, guest-checkout notes — are collected too. Text was collected while an administrator looked at a page, and an administrator is logged in: those words were never collected, and every visitor saw them in the source language. Now, after an administrator has read a page, the site reads it once more by itself as a guest, in the background, once a day per page.
* New: content loaded after the page — «Load more» buttons, product filters, quick views, infinite scroll — comes back translated, with its links in the language. Themes and plugins fetch those pieces through admin-ajax; the page engine never saw them, so on /it/ everything loaded after the first screen was in the source language.
* New: the REST API answers a translated page in its language: WooCommerce's blocks (All Products, filters, the cart), client-side navigation and headless themes get product names, titles, excerpts and descriptions translated, permalinks in the language. Ids, slugs, prices and the editor's own requests are untouched.
* New: the sentences a theme or plugin hands to its scripts — «Product was successfully added to your cart», «View cart», «Loading…», Elementor's «Close», «Next», «Share on Facebook» — are translated and collected like any other text. A paid theme without language packs (WoodMart, Flatsome, Avada) showed them in English on every language. This reads a JSON handed over as a string too (WooCommerce's address labels «Town / City», «Postcode / ZIP», Kadence's countdown labels), a theme's own `const` or `window.name = {…}` block, and a block printed by hand in the page head.
* New: feeds of a translated language (/it/feed/, Atom) carry translated titles, excerpts and bodies, with links in the language. Feed readers, newsletter tools and Google Discover read that file.
* New: any `data-*` attribute whose name says it holds words (`data-product-title`, `data-none-results-text`, `data-toast-cta`, `data-tooltip-message`…) is translated, as are `data-alt` on sliders, Bootstrap's `data-bs-title` tooltips, bare names like `data-label` or `data-caption` and numbered series like `data-button-transition-text-1`; analytics labels are left alone.
* New: import from Autoglot. Its table of paid translations — page sentences and the owner's own replacements, in every language it served — is read straight from the database, with Autoglot switched off; translated addresses and sentences it never finished are left out.
* New: Ninja Forms fields — labels, placeholders, options, the submit button — are translated before the form is drawn. Fluent Forms is recognised (its messages too).
* New: a visitor who signs up on /it/ keeps that language: WordPress' password-reset and new-account e-mails, and WooCommerce's account e-mails, go out in it.
* Improved: SEO plugins. `og:locale` now names the page's language whatever the site locale is (Yoast, Rank Math, All in One SEO, SEOPress); no second `og:locale` with All in One SEO; our multilingual sitemap is listed in All in One SEO's and SEOPress's sitemap index too.
* Improved: a breadcrumb («Home / Rooms / Sea view»), a list of tags or a pagination is no longer taken for one sentence: each link is translated on its own, and the product's name there is the same one as on its page. An icon-only link inside a sentence no longer turns the sentence into a unit.
* Improved: the switcher's live preview shows exactly what visitors will see: a language still offline is left out of it and named underneath, instead of being drawn as if it were online.
* Improved: right-to-left languages keep their direction — and load the theme's and WooCommerce's `-rtl.css` — even when «Translate the interface» is off.
* Improved: imports from Polylang and WPML bring the translations of categories, tags, product categories and attribute values, the purchase note, product attributes, variation descriptions and Advanced Custom Fields; the copy cleanup checks them before offering to trash a copy.
* Improved: imports from Polylang and WPML read pages built with SiteOrigin's Page Builder and Beaver Builder, whose text lives in a serialized field, not in the page content — as Elementor and Bricks already were.
* Fix: a TMX or CSV brought back into the site keeps the pairs that read the same in both languages («Agrigento» stays «Agrigento»): they are decisions, and the round trip export → import lost them. The «What to do next» guide no longer says «Everything is translated» while a new phrase is waiting, when a deleted string left a translation behind.
* Fix: a picture chosen per language is also swapped where ShortPixel, EWWW and a3 Lazy Load park the real address (`data-lazy-src`).
* Fix: WooCommerce e-mails sent from the dashboard («Completed», a note to the customer) are translated; variations («Linen shirt – Blue») and product names inside WooCommerce's sentences too; searching on /it/ finds products by their translated name.

= 1.5.8 =
* Fix: WooCommerce e-mails sent from the dashboard — «Completed», a note to the customer, a resent invoice — were never translated: the customer who ordered in Italian got them entirely in English. Each e-mail is now written in its reader's language: the customer's in the language of the order (subject included, from WooCommerce's own language pack), the shop's own notifications in the site language — before, the shop received them in the customer's language.
* Fix: variations and product names inside WooCommerce sentences stayed in the source language — «Linen shirt - Blue» in the cart, on the thank-you page and in the e-mails, «“Blue mug” has been added to your cart», «Be the first to review “Blue mug”», the breadcrumb's last step and the quantity label read by screen readers. Now they are translated like the product itself; this works for any theme or plugin that quotes a name inside its own wording.
* New: searching on a translated page finds what the visitor typed in their language — «tazza» on /it/ finds the product stored as «mug». It was the most reported problem in the forums of other translation plugins.
* New: WP Rocket integration. WP Rocket now knows your languages, as it does with WPML, Polylang and TranslatePress: a page excluded with «Never cache this URL» (or its box on the edit screen) is also excluded in every language — the /it/ copy of a members' page was cached before; the empty mini-cart it keeps is kept per language instead of one for everybody; cart, checkout and account are excluded in every language; «Clear cache» offers each language; «Remove Unused CSS» keeps the language switcher's styles.
* Fix: imports from Polylang and WPML now bring the translations of categories, tags, product categories and attribute values (Red → Rosso in the variation choices), the purchase note, the attributes typed in a product, variation descriptions and Advanced Custom Fields filled in the translated copy. The copy cleanup no longer offers to trash a copy whose fields were not imported yet.
* Fix: a big TMX or CSV import (2,000 translations) could stop halfway with a server error on hosts that limit a request to 40 seconds. It now runs in one database transaction: the same file takes a few seconds.
* Fix: WooCommerce checkout: the address labels (Town / City, Postcode…) no longer show in English for a moment when the page opens or the country changes.
* Fix: in the block cart, attribute labels («Colour:») are translated.
* Fix: structured data for Google: a title composed as «Product - Site name» is translated.
* Fix: with themes that restyle every button (Hello Elementor), the open language menu kept the current language white on white and narrower than the menu.

= 1.5.7 =
* Changed: the «Labs ✨» page describes the free engines of TranslateRocket Labs as free translation engines, without naming third-party services.
* Readme: a new question for people without Chrome or Edge, and an animated first screenshot.

= 1.5.6 =
* New: when you deactivate the plugin, «Send and deactivate» sends your reason to the developer — anonymously, and only if you press it. Until now the answer stayed on your site, and nobody ever learned why people left. «Skip and deactivate» sends nothing; the box shows exactly what is sent (versions and a few counts, no site address, no name, no e-mail).
* Improved: the request for a review now comes at a better moment and never gets in the way. It appears only on TranslateRocket's own screens (never on Posts, WooCommerce or the Dashboard), after 3 days and 50 real translations — empty or waiting rows no longer count. «Maybe later» and the × put it off for three weeks, twice at most; «I already did», «No thanks» and «Write a review» close it for good. Before, the × closed it forever, so someone busy at that moment was never asked again. «Maybe later» on the donation note now puts it off for 60 days instead of closing it.
* New: a «Labs ✨» page tells you what TranslateRocket Labs adds — a free add-on, on request, that translates with no API key from any browser, phones included, and does more of the work by itself. It shows on the plugin home and on AI Translation, and can be folded into one line. It opens only inside TranslateRocket, never as a notice elsewhere, and disappears once Labs is installed.
* Improved: «Reuse saved translations» → «All except free machine translations» now also leaves out what the free engines of TranslateRocket Labs translated, not only the browser translator. Whoever moves to an AI gets the AI quality on repeated sentences too (menus, footer, buttons); your own edits, imported and AI translations are still reused.
* Fix: a page whose `<html>` or `<body>` carries `translate="no"` is translated again. That attribute tells Chrome, Edge and Safari not to offer their own translation — Weglot writes it, and so do owners who dislike the browser's popup — but TranslateRocket read it as «skip the whole page» and left the site untranslated with no explanation. `translate="no"` on a part of the page is still respected.
* Fix: 16 more tracking-only parameters no longer stop a translated page from being cached — first of all `srsltid`, which Google Shopping adds to every click on a product, so on a shop most paid traffic was translated again at every visit. Also `ref`, `dclid`, Pinterest's `epik`, LinkedIn's `li_fat_id`, Matomo's `pk_campaign` and others, as the main cache plugins do. A page with a real parameter (a search, a filter) is still never cached.
* Fix: product SKUs (`.sku`) are never translated, even when a translation for the same text exists: a customer quoting a translated code to support, while choosing a variant put the original back, saw two codes on one page.
* Fix: while a language is not online yet, the redirect that sends visitors back to your main language is marked «do not cache», so no cache in front of the site keeps sending them away after you press «Go online».
* Fix: importing again no longer overwrites the translations you corrected by hand. Importing a second time — because you translated more in the other plugin, or to be sure — brought back the old text over your corrections, and the count stayed the same so nothing showed it.
* Fix: Polylang, WPML and Bogo imports take only published, private or scheduled translations. Drafts, pending ones and translations in the trash — often binned on purpose because they were wrong — were imported as good ones.
* Fix: a Norwegian site (Bokmål, `nb_NO`) imported nothing from Bogo, Loco Translate and Multilanguage, without saying so. It now lands in Norwegian.
* Fix: qTranslate-XT, WPGlobus and WP Multilang markers with a region — `{:en_US}`, `{:pt_BR}`, `{:zh_CN}` — are understood. With the source written `{:en_US}` the whole post was skipped.
* Fix: a TMX file from Trados, memoQ or OmegaT, which write the source language as `en-US` or `en-GB`, imported zero translations. The source now matches like the target languages already did.
* Improved: NitroPack and Cloudflare (the official Cloudflare plugin, with its page cache or APO on) are now refreshed when translations change, so a corrected translation no longer waits for their cache to expire. The call goes out once, a minute after the last change, so a bulk translation does not call their API hundreds of times.
* Developers: another plugin can now add a translation provider with the `trrocket_providers` and `trrocket_provider_defs` filters. It then appears on the AI Translation screen (with no key field, if it needs none) and works everywhere the built-in ones do: bulk translation, the fallback chain, the visual editor.

= 1.5.5 =
* Fix: sentences you translated with an older version show up translated in the visual editor again. Older versions collected a sentence with a link, a bold word or a line break as separate pieces, and newer ones read it as one; visitors kept seeing it translated, but the visual editor showed it in the original language with an empty box, as if the work were lost. The editor now shows it as visitors do, with the box already filled, and once after the update every such sentence whose pieces are all translated gets its whole translation saved — exactly what visitors already read. Sentences with an untranslated piece and translations you wrote yourself are left alone, and nothing is deleted.
* Fix: «Translate everything in this browser — no key» no longer leaves you waiting on a browser that cannot do it. The button turns off, a progress bar shows the one-time download of the language model and then each sentence, and if the download stalls or the first sentences fail, a box right under the button explains why and offers three free ways: a free Gemini key (5 minutes, no card) with a step-by-step guide, copy → Google Translate → paste back, or a desktop Chrome or Edge. Before, the only sign was «0 translated · 12 ⚠» after minutes.
* Fix: the setup wizard tells you at the translation step when the browser you are using cannot translate by itself (phones, Firefox, Safari), and points to the free Gemini key guide.
* Fix: «Only flags on phones» hid every language name except the current one, which stayed on screen next to its flag. Found by the new live preview below.
* Fix: in the dropdown switcher, a language name that is short in letters but wide on screen could be cut off in the open menu. The width now comes from the widest name as drawn, not from the one with the most letters.
* Fix: admin screens no longer jump at every click. Notices from WordPress and other plugins were printed above the screen and moved under the title only once the page had finished loading — on a slow site after 2–3 seconds, pushing everything down and back. They are now in place from the start.
* Improved: the switcher's live preview is now your real switcher, drawn by the same code and CSS as your site in a frame of its own. It follows every change before you save — layout, names, colours, divider — opens and closes like on the site, and has a Desktop / Phone view. Before, it was a copy that cut names short in the dropdown and showed layout changes only after saving.
* Improved: changing, adding or deleting a switcher profile, or saving, brings you back to where you were on the page, not to the top.
* Improved: «Load available models» says what went wrong, right next to the button: no key yet, key refused, too many requests, or the site cannot reach the provider. Before, every case showed the same browser alert.
* Found with a new check that installs TranslateRocket on a brand-new WordPress (Astra + Elementor), follows the setup as a first-time user would, and times it — on a phone-sized and a desktop screen.

= 1.5.4 =
* New: choose what the AI may reuse from the translation memory (AI Translation → Translation memory): everything (the cheapest), everything except what the free browser translator wrote, or nothing. Moving from the free Chrome/Edge translation to an AI, every repeated sentence — menus, footer, buttons — used to be copied from the browser version and never reached the AI. Glossary terms always apply, and the browser translator itself keeps reusing everything, since it costs nothing.
* New: «Improve N browser translations with AI» on the Memory screen. It sends only the sentences the browser translator wrote to your AI provider; a sentence that has a hand-written version elsewhere is copied instead of paid for, and a translation a person saved is never touched.
* Fix: every admin screen fits a phone. The translation panel under the page editor squeezed the translation to one letter per line; it now shows one card per sentence, original above and translation below. The same for the translation memory, the list of pages and the progress per language; the AI provider cards no longer run past the right edge, and the language visibility menus fit the editor sidebar.
* Fix: the floating language switcher no longer covers the buttons of a cookie banner. It stays above banners, as since 1.5.2, but now also moves up above any bar fixed to the bottom of the screen, and comes back down when the bar goes away.
* Fix: the setup wizard shows only its three steps, without notices from TranslateRocket or other plugins.
* Improved: in the list of pages, «Redo» is now «Start over» and «✖» is now «Hide» (nothing is deleted), with an info icon explaining every button; the Undo link says what it puts back.
* Tested on a phone-sized and a desktop screen, 17 screens and pages checked automatically, including the visual editor and the public site as a visitor.

= 1.5.3 =
* New: import from Falang and Sublanguage. Both keep the translation of a page as extra fields on the original page, not as copies; TranslateRocket reads them straight from the database, so the import works after the other plugin has been switched off. Only what Falang marks as published comes across, and an empty field - which both plugins read as "use the original" - is not imported as a translation. The translated page addresses come across too (/it/chi-siamo/ stays /it/chi-siamo/), so the links search engines already know keep working. Menu labels typed by hand come across as well, and so do the site title and the widget texts saved by Falang.
* New: when an import would do harm, it stops and says why. If the plugin you are coming from says your site is written in another language than the one set in TranslateRocket, every sentence would be paired with the wrong side; now nothing is imported and a message explains what to change, instead of a silent "0 imported".
* Fix: after switching off a translation plugin, pages no longer send visitors to the home page. Falang, Sublanguage and others leave their own address rules behind; WordPress kept reading addresses with the rules of a plugin that was gone. The rules are now rebuilt on the first visit after any plugin is switched off.
* Fix: the page title in the browser tab, in search results and in social previews is translated even before anyone translates it as a whole. Themes and SEO plugins glue "Page title - Site name" together; that glued sentence never existed in the plugin you imported from, while both pieces did. It is now put together from its translated pieces, and a translation of the whole title, when there is one, still wins.
* Fix: texts that visitors read but that live in data attributes are translated: the column headings WooCommerce and Tutor LMS show on phones, the "Sending..." text of Beaver Builder buttons, loading texts, tooltips (BuddyPress included) and data placeholders. Every other data attribute is left alone on purpose: they are ids and keys that scripts depend on.
* Fix: Divi 4 texts written differently for desktop, tablet and phone are translated for every device. Divi keeps them in a data attribute and puts them on screen with JavaScript, so a phone showed the original language.
* Fix: OpenAI's reasoning models (o1, o3, o4-mini, gpt-5 and later) work. They refuse the fixed "temperature" TranslateRocket sent for steady translations, and every request failed; it is now sent only to the models that accept it, with one more try without it for any model not known yet.
* Fix: the Gemini key travels in a request header, as Google now documents, instead of in the address, where addresses end up in server logs.
* Fix: a DeepL key sent to the wrong server (free and paid keys live on different ones) is retried on the other one instead of failing.
* Fix: identifiers made of words joined by underscores, and lone codes with digits in them, are no longer collected as text to translate.
* Tested with the real Falang and Sublanguage plugins; 682 automated checks in 45 suites, including the update from the version on WordPress.org.

= 1.5.2 =
* Fix: the text of a submit button is translated. That is the button of the WordPress comment form ("Post Comment"), the search button of many themes and the login button of Divi: they all keep their text in an attribute, which was never read, so those buttons stayed in the original language on an otherwise translated page. The value of a text field, a checkbox or a hidden field is deliberately left alone: there it is data being submitted, not a label, and translating it would break the form.
* Fix: a picture with a version of its own per language now reaches the eye. Until now only a lone <img> was swapped; inside a <picture> the browser picks the <source> beside it - which is what WebP plugins produce - so the translated picture never appeared. The same now works for a video poster, for video and audio sources, for the retina version in srcset, and for lazy loading, which used to put the original picture back half a second later.
* Fix: the title of an SVG icon is translated. It is the name a screen reader says out loud, and it was skipped together with the title of the page.
* Fix: visitors arriving from a campaign, a social network, a newsletter or a QR code now read a page from the cache like everybody else. Their address carries tracking parameters (utm_source and the like), and any address with a parameter was treated as a page of its own that could not be cached - so the most expensive traffic was the slowest.
* Fix: an edited translation shows on the site immediately. Clearing the page cache was repeated by hand in a dozen places and missing from others; it now happens inside the saving itself, once per request, whether you save one sentence or import ten thousand. The same for sites with Redis or Memcached, where the per-page maps could stay up to twelve hours behind, and for WP Fastest Cache, which was never cleared at all.
* Fix: optimization plugins are told to leave the language script alone. It runs in the page head to pick the visitor's language before the page is painted; with "delay JavaScript until interaction" it was postponed to the first tap, so the visitor read the wrong language, and the language picker did not open on the first click. Autoptimize, LiteSpeed Cache, WP Rocket, SiteGround Optimizer, WP-Optimize and W3 Total Cache are all told now.
* Fix: the floating language picker is no longer hidden behind a cookie banner.
* Fix: the subject of a WooCommerce email is translated into the language of the order. The body already was, and the subject is the first thing read in an inbox.
* Fix: file names, template placeholders like ${name}, style strings, email addresses, colours and product codes are no longer collected as text to translate. They were paid for like any other phrase and came back changed: a translated file name makes the picture disappear, and a "localized" email address stops being clickable. Seen on real multilingual sites while comparing them with their translations.

= 1.5.1 =
* Fix: coming from qTranslate-X, qTranslate-XT, WPGlobus or WP Multilang, once that plugin was switched off every page showed all of its languages one after the other, with the language markers in plain sight - the title first. The public site now shows only the part in your source language, and TranslateRocket translates it like any other text. Nothing in your database is changed, and switching the old plugin back on brings everything back as it was.
* Fix: imported sentences with a link or a bold word in them are now used on the translated page when they come from Weglot, Loco Translate, Multilanguage, qTranslate, WPGlobus or WP Multilang. Weglot marks those words in its export in its own way; they are now read.
* Fix: from TranslatePress, a sentence left identical by machine translation is no longer imported as its own translation. A name you kept identical on purpose, approved by a person, still is - so automatic translation never touches it afterwards.
* Fix: a TMX file exported from TranslateRocket and imported again no longer loses the translation of labels and social titles that share their words with page text. A TMX from another tool now works with straight apostrophes and dashes, and reaches every place those words are used on the site.
* Tested with the real plugins, in Italian, German, French, Arabic and Chinese: Bogo, TranslatePress, qTranslate-XT, WPGlobus, WP Multilang, Multilanguage, Loco Translate, plus Weglot and TMX/CSV files.

= 1.5.0 =
* New: a sentence broken by a link or a bold word is now translated whole. Until now "Read the <a>booking conditions</a> before you confirm." reached the translator as three separate pieces, so nobody could put the words in the order German or Japanese needs, and "Read the" on its own is not translatable at all. The sentence now travels in one piece with numbered marks where the tags are, and the translation is put back into your own links: the address of a link always comes from your page, never from the translation. Sentences already translated keep what they have, so nothing you have done is lost, but the count of phrases to translate will go up: the whole sentences are new to the plugin.
* New: "Next steps", a screen of its own, first in the TranslateRocket menu, with a number beside it when something is waiting. It says where your site is right now and what is left to do, with a button for each step, and it is worked out from your site every time you open it. The same panel appears at the top of the main screen. It also says, plainly, when there is nothing to do: the steps that tell you to leave something alone matter as much as the ones that ask for work.
* New: while another translation plugin is active, an administrator looking at the public site now sees one line saying that TranslateRocket is standing aside on purpose and nothing is broken. Somebody spent hours hunting a fault that was not there, because the right behaviour and a broken plugin looked identical.
* New: the menus another plugin keeps one per language are now named on the Import screen, with the reason you can leave them exactly where they are. Switching that plugin off keeps the menu of your main language in every position; the others simply stop being used.
* New: deactivating TranslateRocket asks once, and only once, what went wrong. Answering is optional, the plugin deactivates either way, and nothing is sent anywhere: the answer stays on your site and a button copies it for you if you want to send it yourself.
* New: the support screen and the support page now say exactly what makes a report easy to fix: the address of a page, the exact words, and the piece of the page copied as code.
* Fix: a page built with a page builder now brings its translations with it. Elementor keeps every word of a page in a meta field of its own, not in the page content, so importing from WPML or Polylang used to bring over the title and the excerpt and nothing else — on exactly the sites with the most translation work behind them, since Polylang or WPML plus Elementor is one of the commonest ways to build a multilingual site. The two copies are now read side by side and paired widget by widget, by the id of the widget, so a widget added in one language only does not throw everything after it out of line. Anything identical in both languages is left alone, and an address is never stored as the translation of another address. Bricks is read the same way. Found while looking into what a user who left had been through.
* Fix: translations imported from Polylang, WPML and the other plugins that keep a copy of each page per language are now actually used when a sentence has an apostrophe, quotes, a dash or an ampersand. WordPress shows "don't" as "don’t" and " - " as " – ": the imported sentence was stored as it was typed, the page was read as it is shown, the two never matched, and the page stayed in the source language with nothing to say why. Both shapes are stored now.
* Fix: a sentence that is the same in both copies is no longer imported as its own "translation". It used to count as translated, stay in the source language on the translated page, and be skipped by automatic translation for good.
* Fix: an ampersand in an imported translation no longer shows up as "&amp;" on the translated page.
* Fix: blocks that keep their text in their settings rather than in their HTML — Spectra 3 is one — are imported too. On a page built that way, only a handful of lines used to come across.
* Fix: an imported paragraph with a link or a bold word in it is now used on the translated page. Since 1.5.0 the engine reads such a sentence whole, with numbered marks where its links are; the importer stored it with the links stripped, so the two never matched. Imported sentences now take the engine's own shape, and are paired only when both copies carry the same links in the same places.
* Fix: the import no longer takes styles (gradients, colours), a pattern's own description or text damaged by a bad save for sentences to translate.
* Fix: after the switch from WPML or Polylang, an old address under that plugin's own language prefix - /zh-hans/ where TranslateRocket uses /zh/, and likewise zh-hant or pt-pt - answered "page not found". It now leads to the translated page with a permanent redirect. Only prefixes the other plugin really used on your site are recognised, only addresses that would otherwise be "not found" are touched, and nothing changes while the other plugin is still active.
* Fix: a copy left by WPML or Polylang whose text had all been imported was reported as having one text not imported when a sentence contained an ampersand or a typographic apostrophe, so it was offered to be kept and stayed online as a second page. The review now compares the sentences in the same shapes the import stores.
* Fix: the advice about headers and footers in several languages never actually appeared. The templates were read with a query that Polylang and WPML filter by language, so the plugin saw one language, concluded there was nothing to say, and stayed silent — exactly on the sites that needed the advice. They are now read straight from the database. The same screen also names the menus another plugin keeps per language, and the product template of a page builder, which were missed before.
* Fix: the advice about headers and footers in several languages used to say the copies "can go" without saying that you do not have to change anything and that they come straight back from the Trash. Written that way, it could cost somebody their header.
* Fix: WordPress strips anything between angle brackets when it cleans up a form field, which would have thrown away the marks inside a sentence: a correction typed by hand could never have been saved. Corrections that lose those marks are now refused with an explanation instead of being stored unusable.

= 1.4.6 =
* New: the names in "Words & phrases" (Exclusions screen) now stay as they are inside sentences too. Until now a name was protected only when the whole text was the name: "LifeStyle-Shop" alone stayed, but "Willkommen im LifeStyle-Shop" came back from DeepL as "Benvenuti nel negozio LifeStyle". Now DeepL receives the name marked with its own "do not translate" tag, Google Cloud with translate="no", and the AI models are told which names to copy exactly. Sentences without a protected name are sent exactly as before. Sentences already translated keep their translation: correct them in the visual editor, or use Redo on the page to translate it again. Asked for by a shop owner in Switzerland.

= 1.4.5 =
* Fix: a page edited in the block editor now reaches visitors at once. The block editor saves over the REST API, and the cache of translated pages was only being cleared from the classic admin screens, so visitors kept seeing the old translated page for up to six hours while the administrator - never served from the cache - saw the new one. The same happened to a product renamed through the store API and to a header or footer edited in the Site Editor of a block theme. Reported by a site that put a page back into separate blocks and kept seeing the old single block on the translated pages.
* Change: the cache of translated pages is also cleared when a page is trashed or restored, and when widgets, menus, the customizer or a product are saved outside the admin screens. Autosaves and revisions never clear it, since every clearing also purges the host cache.

= 1.4.4 =
* Fix: words that a script writes into a placeholder already on the page are collected too. Consent plugins do exactly that - Complianz prints "{title}" in the banner and fills in the names of your privacy and legal pages when the script runs - and those two links could not be translated at all, because TranslateRocket was only watching for text that gets added, not for text rewritten in place. Reported with a screenshot, which is the only way it could have been found.
* New: coming from Polylang or WPML with a header and a footer per language? The Import screen now says so, and says what to do: TranslateRocket translates the one header and the one footer you already have, so the copies can go and a single switcher replaces the three language menus. Text inside a duplicated template could never be translated - it was a second template that had never been in the source language - and nothing explained why.
* Change: the Translations screen now says where the text of pop-ups and cookie banners comes from: it appears once you have opened the pop-up yourself, as an administrator, on a page in your source language.

= 1.4.3 =
* New: in the visual editor, text that JavaScript adds to the page - a consent banner, a pop-up - can now be clicked and translated like the rest of the page. Until now only the text printed by the server could be clicked; the banner had to be translated from the Translations list. Tested with Complianz, CookieYes, GDPR Cookie Compliance and Cookie Notice.
* Fix: consent banners that build themselves the moment the page is ready (CookieYes among them) are now collected too - the collector was starting a few milliseconds after them. Tested with CookieYes, GDPR Cookie Compliance and Cookie Notice: the banner text reaches the translation screens and visitors see it translated.
* Fix: page builders at work are left alone. When Elementor, Beaver Builder, Divi, Bricks, Oxygen, Breakdance, Brizy, WPBakery, Thrive Architect or the Customizer load a page to edit or preview it, TranslateRocket no longer collects their interface text ("Edit Header", "Drag widget here"...), no longer translates the canvas and hides the floating switcher there. Header, footer and popup templates opened on their own are not filed as pages either. New filters: `trrocket_builder_request`, `trrocket_builder_template_types`.
* Fix: text meant for administrators only is no longer collected as page text. Debug panels, page-builder helpers and notes tools (Query Monitor, Elementor's editor helpers and Notes, the admin bar) are left alone, both in the page and in the text JavaScript adds later; and text JavaScript adds while hidden - dialogs, templates, collapsed helpers - is not collected until it is actually shown. The `trrocket_tool_prefixes` filter extends the list.
* New: the separate pages left by Polylang, WPML or Bogo are now easy to spot. Once that plugin is deactivated, each copy is labelled in Pages and Posts ("Left by Polylang · Français — original: About us"), and a notice on those screens and on the Dashboard counts them and leads to "Review the separate pages".
* New: "Translate again" for one page. In the Translations list every page now has a Redo button (and an X to remove it from the list): it removes that page's translations and its translated address for the language, so the page is translated from scratch with AI, in the browser or by hand. Nothing is lost: an Undo link puts everything back, and the last ten removals are kept.
* Change: "Review the separate pages" says clearly that a page restored from the Trash is back at its old address at once.
* Fix: text that JavaScript adds after the page has loaded - cookie and consent banners, pop-ups, AJAX results - now reaches the translation screens. When an administrator views a page in the source language, that text is filed with the page like the rest, so it can be translated and is then shown translated to visitors. Before, only text already translated elsewhere could be shown, so most cookie banners stayed in the source language.
* Thanks to Alain, who tested every beta of this release on a real Polylang + Elementor + Forminator site and reported each of these issues with patience and precision.

= 1.4.2 =
* New: side by side, the preview is one click away. The Languages page shows a Preview panel with a button for each language, the admin bar has a Preview menu that opens the page you are looking at in another language (and a way back to the live site), and every published row in Pages and Posts has a Preview link. Before, the preview meant typing ?trr-preview= into the address.
* Change: when the browser cannot translate, the panel now says what the translator built into Chrome and Edge needs (Windows 10 or 11, macOS 13+, Linux or ChromeOS but not Windows Server, 16 GB of RAM or a graphics card with more than 4 GB, 22 GB of free disk space, Edge 148+, https), instead of only saying that the browser has no translator.

= 1.4.1 =
* Fix: validation and "message sent" messages of forms added with the Elementor widget, the Forminator block, a widget area or a template stayed in the source language; the message translator was loaded only when the form was a shortcode in the page content. It is now loaded whenever a Forminator, Contact Form 7, WPForms, Gravity Forms, SureForms, Formidable or Ninja Forms form actually appears on a translated page.
* New: Forminator messages returned by the server (thank-you message, invalid form, field errors) and forms loaded with "Load form using AJAX" are shown in the visitor's language.
* New: Forminator e-mail notifications are sent in the language of the page the form was submitted from. Their subject and body, and the form's messages, are listed under "Forms: messages and e-mails" in the translation screens. The `trrocket_forminator_translate_notification` filter keeps a notification in the source language.
* New: PHP functions for developers, `trrocket_current_language()` and `trrocket_default_language()`.
* Fix: side-by-side mode no longer switches itself on when another translation plugin is activated on a site that TranslateRocket was already serving: the translated addresses stay online, and a notice offers "Run side by side" instead.
* Fix: when the other translation plugin goes away without anyone opening wp-admin (WP-CLI, a folder removed, another site of a network), the translations are still shown to administrators only until "Go online".
* Fix: after "Go online", languages that are still offline are named in the notice, with a link to switch them on.
* Fix: side by side, the pages served by the other plugin in its own languages are no longer collected as source text.
* Fix: side by side, blocks and menu items limited to some languages are not hidden on the other plugin's pages.
* Fix: on a previewed page (?trr-preview=xx) the links keep the preview; the "Translate my homepage now" button of the setup wizard opens a preview instead of the other plugin's address. Preview pages also send noindex and no-cache headers.
* Fix: on a fresh install the source language is derived correctly for Norwegian (nb_NO, nn_NO) and Traditional Chinese (zh_TW, zh_HK) sites, and falls back to English for locales the catalogue does not have instead of a code that matches nothing.
* Fix: the forms message translator and Forminator only use languages that are online for visitors; an offline language stays private to administrators.
* Fix: a form message, e-mail body or AJAX-loaded form containing a stray closing tag is left untouched instead of being cut short.
* Fix: uninstalling with "delete data" also removes the side-by-side, wizard, log and cache options.
* Fix: three interface strings that shipped untranslated ("%1$d of %2$d translated", the "Want a hand with your site?" card).

= 1.4.0 =
* New: side-by-side mode. TranslateRocket can now be activated next to WPML, Polylang, TranslatePress, Weglot, GTranslate, qTranslate-XT, WPGlobus, WP Multilang, Bogo or Multilanguage without changing anything on your public site. While the other plugin is active, visitors see the site exactly as before — the same addresses, language switcher, sitemap and language. Meanwhile you can import its translations, complete them and preview any page as an administrator by adding ?trr-preview= and a language code to the address (for example ?trr-preview=it).
* New: going online is your decision. When the other translation plugin is deactivated, the translations are shown to administrators only, on their real addresses, until you have checked them and click "Go online".
* Change: "Review the separate pages", which tidies up the copies Polylang, WPML or Bogo left behind, stays locked while that plugin is still active, so no page is taken off a site that is still using it.
* Change: the languages you choose in the setup wizard now start offline, as they already did on the Languages page: only you see them while you translate, and you put each one online when it is ready.
* Fix: activating the plugin no longer switches the site's interface language (for example to Italian) before you have chosen any language to translate into.
* Fix: on a new installation the source language is now the language of the site, instead of Italian.
* Fix: the first-visit redirect to the visitor's browser language no longer sends visitors to a language that is still offline.

= 1.3.0 =
* New: tidy up the pages Polylang, WPML or Bogo left behind. Those plugins keep a separate page for every language; once their translations are imported, TranslateRocket translates the original page itself, so each copy is a second place to edit the same page. Under the importer, "Review the separate pages" lists every copy with what was found: copies whose text is all in TranslateRocket can go to the Trash, copies with text laid out differently can be kept as independent copies, and nothing is offered for the Trash before the import or while its language is not active. Nothing is deleted — pages go to the Trash — and the old address of each copy sends visitors and search engines to the translated page with a 301.
* Fix: on a page opened through its translated address (for example /it/chi-siamo/), the hreflang links and the language switcher reused that Italian slug for every language, so they pointed at addresses that do not exist (/chi-siamo/, /es/chi-siamo/). Each language now gets its own address — the original slug, or its own translated one — exactly as the sitemap already did.
* Fix: hreflang links no longer repeat the query string of the visit (?utm_source=…); they name the clean address of each version.
* Fix: a page that does not exist (404) no longer prints hreflang links to the same missing address in every language.
* Fix: WooCommerce block checkout — after placing an order in a translated language, customers landed on the "Order received" page in the site's default language. They now stay in the language they shopped in, as the order e-mail already did.
* Fix: translated addresses now work for WooCommerce products and every other custom post type. A translated slug on a product (/it/product/colazione-in-terrazza/) returned "page not found", while the language switcher and hreflang already pointed there; product links in shop pages now use the translated slug too.

= 1.2.1 =
* New: structured data is translated too. The FAQ questions and answers, article headlines and descriptions that themes and SEO plugins put in JSON-LD for search engines used to stay in the source language on every translated page, and an article on /de/ still declared itself English. They are now collected like the page title and description, translated in every language, and "inLanguage" states the language of the page. Names of people, companies, software and the site are never translated, a video keeps the language it was recorded in, and addresses, dates and prices are left exactly as they are. The data is read and rewritten as JSON, so a translation can never break it.
* Fix: the flag shown for Chinese had a single star, which made it look like another country's flag. It now has the large star with the four small ones beside it.
* Change: Arabic no longer shows a national flag. It is official in more than twenty countries, so no single flag is right for it, and the one usually chosen for it carries a religious inscription that should not be redrawn or used as decoration. Arabic now shows a neutral "AR" marker. If you would rather have a flag, you can still choose one for that language in the custom flag field.
* Fix: a floating language switcher placed along the bottom of the page opens upwards, so its menu is no longer cut off by the edge of the window.

= 1.2.0 =
* New: show content in some languages only. Wrap it in `[translaterocket_language lang="it,de"]…[/translaterocket_language]`, or use `not="it"` to hide it in some; in the block editor, add the class `trrocket-only-it` or `trrocket-hide-it` to any block, navigation links included. Content limited to a language is shown exactly as you wrote it and never re-translated.
* New: menu items for some languages only. Every item in Appearance → Menus has a "Show in" row of language checkboxes. Nothing ticked means every language, so existing menus look exactly as before; an item that is hidden takes its sub-items with it.
* New: translate a whole page in ChatGPT or Gemini, with no API key. In the visual editor's "Translate page" panel, one button copies the text of the page together with a prompt written for your site — your languages, the words you never translate, your glossary and your house style. The prompt asks the AI to keep the line numbers and the formatting markers, so its reply goes straight back into place.
* The box you copy from now selects everything with one click, and the box you paste into selects its content on the first click, so a second paste replaces the first.
* The changelog had grown past the 5,000-word limit of the plugin directory and was being cut off: releases from 1.0.0 onwards stay here, and the full history is in changelog.txt, shipped with the plugin.
* Small tidy-ups: a clearer example in the "Words & phrases" exclusion box, and the LICENSE file now carries the plain GPLv2 text.

= 1.1.4 =
* The plugin's own header now sits on a night sky instead of the rainbow band, the same one used on the project website. The stars are drawn in CSS, so nothing extra is downloaded and the logo finally stands clear of its background.

= 1.1.3 =
* Fix: opening the media library to pick an image for a language left the little "Choose image" buttons — and the image window itself — floating on top of it, over an apparently empty panel. They now step out of the way while the library is open and come back when it closes, Escape included.

= 1.1.2 =
* Fix: **a save that got no answer used to spin for ever.** If your site did not reply — a proxy holding the connection, a dropped network, a security layer swallowing the request — the buttons kept turning with nothing on screen to explain it, and the sentence you had just written was lost if you gave up and closed the box. Requests now stop waiting after thirty seconds, your text stays in the box, and the message tells you whether the site refused the request (with the code) or did not answer at all.
* Fix: the window for swapping an image now opens **in the middle of the screen and can be dragged**, with the same title bar as the text editor. It used to appear glued to the picture — which for a full-width photo at the top of a page meant squashed against the top edge — and its header was drawn with styles that did not exist, so the title, the move handle and the close button ran into each other.

= 1.1.1 =
* New: **a language you add now starts offline.** Until now, ticking a language and pressing save made it public that same second — in the switcher, in your sitemap, in your hreflang tags — with nothing translated in it yet. Now it arrives with its switch grey, and you turn it green when you are ready. A language that was already on your site keeps the state it had.
* New: **the dashboard tells you when a page changed after it was last read.** Text is detected while you look at a page while logged in — so if you edited a page in the block editor and never opened it again, its new sentences were never collected: they did not show up in your list of strings to translate, and on the translated pages they quietly stayed in your source language. That silence is over: the pages are listed by name, with a scan one click away, and the warning clears itself as soon as each page is read.
* Fix: on the Languages screen the per-language progress bar was drawn without a colour, so it looked empty even at 98%. It now runs red to green like every other bar in the plugin.

= 1.1.0 =
* New: **add a language now, publish it when it is ready.** Next to every language you enable there is a switch: green means your visitors see it, grey means only you do. While a language is offline it stays out of the switcher, out of your sitemap and out of the hreflang tags, and anyone landing on one of its URLs is sent to your default language — but you keep working on it on the real pages, because whoever can preview still sees everything. Nothing half-translated ever reaches your visitors or Google.
* New: **the SEO panel in the visual editor now holds everything search engines read**, in one order: the address, the page title, the meta description, the social preview (Open Graph and X), the keywords, then every image on the page and every translatable attribute — titles, placeholders, ARIA labels. Each line takes you to the element: the page scrolls to it, it flashes, and the right editor opens. For a photo that means the image chooser; for its alt text, the text editor.
* Fix: **the social texts were never translated.** If a SEO plugin such as Yoast or Rank Math set an `og:title`, an `og:description` or a `twitter:` card of its own — a different text from the page title, which is the normal case — that text was never collected, so it could never be translated: every share of a translated page went out in the source language. Those texts are now collected like any other, and they show up in the SEO panel.
* Thanks to Simona, for the first donation TranslateRocket ever received.

= 1.0.0 =
* New: import from **Bogo**. It keeps one post per language, linked by two post meta values, so the pairing is exact — title, excerpt and body all come across.
* New: import from **Multilanguage by BestWebSoft**, read straight from its two tables, including category and tag names.
* New: import the translations you wrote **by hand with Loco Translate** — the `.po`/`.mo` files in `wp-content/languages/loco/`. Only your own work is read, not the language packs WordPress downloads by itself: those are thousands of strings nobody on your site chose, and they would bury the useful ones. Entries still marked "fuzzy" are skipped, because nobody has checked them yet.
* New: **a different image for each language.** In the visual editor every picture carries a small button: click it and choose another image from the media library for that language. The picture is swapped on the translated page, `srcset` included — without that the browser quietly reloads the original and the change looks broken. Image addresses are kept apart from the text and are never sent to a translator: a URL comes back mangled and the picture disappears from the page.
* Fix: the Import screen no longer scans every post each time it is opened. It asked each importer whether it had anything, and the qTranslate one had to look inside the posts to answer — on a large site that made the screen crawl. The answer is now remembered for an hour.
* Fix: in the switcher's live preview the dropdown was stuck open. You could see the menu's colours, but never how it opens — which is half of what a dropdown does. The preview now uses the same markup and CSS as the real switcher, so it opens and closes on click exactly like the one on your site.
* Fix: the three settings that only apply to the dropdown layout — how it opens, the arrow, the opening animation — are now switched off when you choose the inline or list layout, instead of looking live while doing nothing. Their values are kept, so changing layout no longer resets them.
* Fix: the live preview now follows you as you scroll the switcher settings, instead of scrolling away after the first section.
* With this release the plugin imports from ten other plugins, plus CSV and TMX.

= 0.10.0 =
* New: import from the qTranslate family — qTranslate-X, qTranslate-XT, WPGlobus and WP Multilang. These keep every language inside the post itself, separated by markers, so the translations are read from your posts and not from the other plugin's tables: the import works even on sites whose plugin was deactivated or deleted years ago, which is the usual case for qTranslate. All four marker styles are recognised, including the HTML-escaped one. Titles, excerpts and body text come across; a post with no section in your source language is left alone rather than guessed at.

= 0.9.9 =
* Change: on a phone the "translate in this browser" button is now shown but switched off, instead of hidden. Chrome and Edge only carry the on-device translator on a desktop, so the button cannot work there — but hiding it meant nobody browsing from a phone knew the feature existed at all. Tapping it now explains where to use it, and the copy-and-paste route beside it still works on a phone.

= 0.9.8 =
* Fix: a browser translation run could reach the end of the progress bar having saved almost nothing. Chrome sometimes discards the on-device translator while a long run is going; from that moment every remaining phrase failed, silently. Measured on a 58-phrase page: 5 translated and 53 failed. The translator is now rebuilt on the first failure and the phrase retried, so the same run finishes 57 of 58 even when the browser drops it eleven times. On the bulk page the counter used to freeze ("Translating 5 of 498...") for the rest of the run; it now keeps going.

= 0.9.7 =
* Fix: the "translate in this browser" button was offered on phones, where it cannot work — the browser translation API only exists on desktop Chrome and Edge. It showed up in the visual editor toolbar, in the phrase popup and on the bulk page, and tapping it got you nothing. The button is now hidden on phones and tablets; on the bulk page the copy-and-paste route stays available, since that one works everywhere.

= 0.9.6 =
* Fix: on a phone, four of the plugin's nine screens ran off the side and the last columns of the tables were simply gone — progress per language, the list of pages, the AI summary. Measured at 390 pixels they overflowed by 116 to 220 pixels. The tables now use less padding and a smaller type on narrow screens, and whatever still does not fit scrolls inside the table itself instead of pushing the whole page sideways.

= 0.9.5 =
* Fix: on a phone, the line that tells you which language your site is written in ran off the right edge of the toolbar, cut in half. It is the sentence that makes the whole bar make sense, so it now gets a row of its own and wraps like ordinary text instead of being clipped.

= 0.9.4 =
* Fix: on a phone the editor toolbar had to be dragged sideways to reach its own buttons — with four languages and the controls it ran past a thousand pixels inside a screen of under four hundred. It now wraps onto as many rows as it needs, and the page below shifts by the toolbar's real height instead of a fixed 46 pixels.
* Change: the Live Preview demo is built for phones too — the cover text no longer sits on top of the photo, where it overflowed the frame and clipped the title and the second button.

= 0.9.3 =
* New: the translator built into Chrome and Edge is now offered on the single phrase too, in the popup of the visual editor — next to Google Translate and "Translate with AI". It was already there for a whole page and for a whole language; the one place it was missing was the one you are looking at while you correct a single line. No key, and the phrase never leaves your computer.

= 0.9.2 =
* Fix: after translating in the browser from the bulk screen, the table underneath still showed the old "0 translated" figures. The message said to reload the page, but the numbers sitting right below it said the opposite — so the work looked like it had gone nowhere. It had not: the translations were saved all along. The screen now refreshes its own totals when it finishes.
* Change: the plugin's description on WordPress.org now leads with the thing that makes it unusual — that Chrome and Edge can translate the whole site on your own computer, with no key, no account and nothing sent anywhere.
* Change: the Live Preview demo is a proper hotel landing page now, not a stack of paragraphs.

= 0.9.1 =
* New: the visual editor can now translate a whole page with the translator built into Chrome and Edge — the same engine the bulk screen has had since 0.8.9, which until now was missing from the one place you are most likely to be standing when you want it. It needs no key and no account, the text never leaves your computer, and the button only appears where the browser can actually do it.
* Fix: the "Translate page" panel always showed an empty grey strip in the middle. It was the progress bar, which is marked hidden but was being shown anyway by one of the editor's own style rules — the same trap that had "Back" and "Finish" visible on the wizard's first step.
* Change: when no AI key is set, the panel no longer just says "add a key, meanwhile use copy-paste". If the browser can translate, it offers to do it.

= 0.9.0 =
* New: ask for help without leaving WordPress. The Diagnostics screen now carries a form that opens a support ticket straight from your site — the technical report goes with it if you want, the answer comes back to you by email, and you can follow the whole thread from a link. Nothing is sent until you press the button, and the page shows you exactly what leaves. If your site cannot be reached from the outside, it says so and points you at the ordinary support page instead.
* New: the three ways to translate now sit side by side on the Translations screen — scan the site for text, hand the whole language to the AI, or let Chrome and Edge do it for free. Each page in the list also gained its own one-click AI button next to Translate, so a single page can be filled in without touching the rest.
* Fix: the setup wizard showed "← Back" and "Finish & start translating" on the very first step, next to "Next →". They were meant to be hidden; WordPress's own button styling was overriding the browser's hidden attribute, so all three were on screen at once.
* Fix: the welcome notice appeared on top of the setup wizard telling you to go elsewhere to pick your languages — which is what the wizard was already asking you to do. It now stays out of the way there, and elsewhere it points at the wizard until you have been through it.
* Fix: the Translations screen counted only the strings already queued for the language you were looking at, so a freshly added language could read "0 still to translate out of 0 detected" while the site was full of untranslated text.

= 0.8.9 =
* New: translate without an API key at all. Chrome and Edge on a computer carry a translator that runs on the device itself, and the bulk screen can now drive it: install the plugin, pick your languages, press the button. It costs nothing, needs no account, and the text never leaves the machine. Quality sits below DeepL and the AI models and it works one phrase at a time, so it is the fastest way to a translated site rather than the best one — and everything it translates is kept, so adding a provider later never repeats the work. It needs a desktop Chrome or Edge and an admin served over https. Where that is not the case — Firefox, Safari, a phone, an admin on plain http — the same panel now says so and points at the copy-and-paste round trip instead, which works in any browser and still needs no key.

= 0.8.8 =
* New: an extra instruction you can give the AI, in your own words — the tone of voice, the words your business does or does not use, names that must stay as they are. It is sent with every translation. The rules about the output format still come last and still win, so a note that goes too far cannot break a batch. Only the AI models read it: OpenAI, Claude and Gemini. DeepL and Google Translate are translation APIs with no prompt of their own, and the settings page says so when one of them is the provider in use.
* New: two more ways to show a language in the switcher — the short code on its own (EN, IT, ES) and the flag with the short code. Full names wrap onto a second line as soon as a horizontal menu carries more than a few languages; "FR" and "PT" do not.
* New: a "No border at all" option for the switcher. Until now the border could only be recoloured, so the only way to hide it was to paint it the colour of the background — which stops working the moment the background is not plain.
* Change: the donation notice says more plainly that the plugin is free forever and stays maintained either way.

Thanks to Nicholas, who wrote in with all three of these suggestions.

= 0.8.7 =
* Fix: with "Redirect new visitors to their browser language" on, picking a language from the switcher was undone straight away and the visitor was sent back. The redirect remembered its decision in a cookie, and Varnish — the cache in front of Cloudways and many other hosts — strips cookies it does not recognise, so that decision never reached PHP and the redirect fired again on every page. The mirror image was true too: on a cached page PHP never runs, so the redirect did not happen there at all. The decision now happens in the browser, which no cache can interfere with, and it works on cached pages for the first time. Clicking a language in the switcher is recorded, so a deliberate choice always wins over the browser's preference.
* Fix: the on-page editor's toolbar followed the language you were translating into. Editing the Dutch version turned the toolbar Dutch. It now follows the language of the person using it, falling back to the site's and then to English — while the page underneath stays in the language being edited.
* Fix: browsing a translated page as an administrator filed WordPress' own already-translated interface as new source text — "Insert/edit link" and friends were recorded in Arabic, Dutch, Romanian and more, waiting to be "translated" into English. Strings are now collected only where the text really is the source language. Site pages still discover everything, and the site scan walks those.
* Fix: in the on-page editor the toolbar hint was cut off mid-word on any screen between 720 and 1400px wide, which is most laptops.

= 0.8.6 =
* New: the admin is now translated into nine languages besides English — Japanese, Dutch, Russian and Polish join Italian, German, Spanish, French and Brazilian Portuguese. The four new ones are complete.
* Fix: the plugin shipped complete Italian, German, Spanish, French and Brazilian Portuguese catalogues and not one of them was ever loaded. For a plugin hosted on WordPress.org, WordPress only reads translations from the language pack in wp-content/languages/plugins; a plugin's own /languages folder is ignored unless the plugin registers it. It now does, so those languages work immediately. If a language pack is published later it still takes priority, so nothing is overridden.
* Fix: only Italian had a compiled .mo. The others shipped as .po only, which PHP cannot read at runtime — they are all compiled now.
* Fix: 136 mistranslations in the German, Spanish, French and Portuguese catalogues, all of the same kind — an English word with two meanings, machine-translated into the wrong one. "API key" had become the key on a keyboard, "Strings" the strings of a musical instrument, "Slug" the mollusc, and Spanish "Save" meant saving money. Nobody had ever seen them, because nothing loaded them.
* Fix: in the on-page editor the toolbar hint was cut off mid-word on any screen between 720 and 1400px wide — which is most laptops.
* Screenshots on the plugin page redone: they were captured too wide, and WordPress.org resizes to 900px before serving, so the text arrived unreadable.

= 0.8.5 =
* Fix: the review request never reached most sites. Dismissing the welcome notice with the standard "x" was not recorded, so the notice returned on every page and the later notices never got their turn. The "x" now sticks, and the welcome steps aside on its own after a week.
* Change: the review is asked for after the plugin has actually done something — at least 25 strings translated and five days in — instead of on day 14 regardless of use. The message says how many strings were translated on that site, and offers a link to support for anyone who has a problem rather than a compliment.
* Fix: four links in the admin notices and on the Help & Feedback screen pointed to pages that do not exist on translaterocket.com and returned a 404 ("Get tips & updates", "Something is wrong", "Send feedback", "Request customization"). They now point to the news and support pages.

= 0.8.4 =
* New: WooCommerce email wording is now translatable. The engine learns strings while you browse your site, which meant phrases WooCommerce only ever prints inside an email — "Thank you for your order", "Quantity", "Price" — could never be collected, so order emails came out only partly translated. Customer emails are now scanned as they are sent and their wording is filed under "WooCommerce emails" in the translation screens, ready to translate by hand or with AI. Scanning happens once per template, not once per order.

= 0.8.3 =
* Compatible with WordPress 7.1.
* Fix: the language switcher block now uses Block API version 3. WordPress 7.1 always runs the post editor inside an iframe, and a block still declaring version 2 made the whole editor fall back to the old non-iframed mode — for every block on the site, not just this one. Editing is unchanged, the editor simply keeps its modern behaviour.

= 0.8.2 =
* Fix (important): on translated pages, markup written inside `<script>`, `<style>` and `<textarea>` could lose its closing tags. Inline JavaScript that builds HTML (`'<span><i></i></span>'`, `.append('<li>…</li>')`, `document.write(…)`) came out broken, and CSS using inline SVG data URIs (`mask-image`, `background-image`) lost the closing `</svg>`, so the shape silently failed to render. The page HTML parser treats those elements as raw text, and any `</name>` inside them was being dropped; their contents are now passed through untouched.

= 0.8.1 =
* New: per-switcher device visibility. Each switcher profile has a "Show on" option — Desktop and mobile, Desktop only, or Mobile only — so you can design one language menu for desktop and a different one for mobile, each hidden on the other (breakpoint 783px).
* Fix: importing from WPML/Polylang/TranslatePress on a large site could hit the host's execution-time limit and silently do nothing. The migration importer now raises the time limit (as the CSV/Weglot importers already did) and clears caches when finished, so imported translations show up right away.
* Fix: the multilingual sitemap is now served with a 200 status. Some setups returned a 404 for it, which made search engines skip the sitemap.

= 0.8.0 =
* New: Weglot importer. Export your translations from the Weglot dashboard (Translations → Export, CSV) and upload the file in TranslateRocket → Import: word_from/word_to columns are detected automatically, language columns are mapped to your configured target languages, and rows for unconfigured languages are skipped and reported.
* New: DeepL quota meter. When a DeepL key is set, the AI page shows the character usage for the current cycle (with a warning as it approaches the limit) straight from DeepL's usage API.
* New: provider outage notice. When a provider runs out of quota or its key is refused mid-run, wp-admin now shows a dismissible warning explaining that the fallback chain took over — previously the switch was silent.
* Improved: DeepL's "HTTP 456" error now reads as a clear "monthly character quota exhausted" message in the visual editor and logs.
* Fixed: Italian translation of "Live preview" in the bundled catalogue.

= 0.7.9 =
* New: Preview mode ("Who sees the translations" in Settings). Keep the translated site visible to administrators only while you review it — visitors keep seeing the default language: language URLs redirect to their default-language page, the switcher is hidden and no hreflang/sitemap signals are sent. Perfect for checking an import from TranslatePress, Polylang or WPML on the real rendered pages before going live. A standing admin notice reminds you while it is on, and the `trrocket_preview_capability` filter lets you open the preview to other roles.

= 0.7.8 =
* The WPML importer is now properly documented (it has been in the plugin all along): bring over WPML's string translations and post-based translations (titles, slugs, matching body text) from TranslateRocket → Import. It reads straight from WPML's tables, so it works even with WPML already deactivated.
* Shipped es/fr/de/pt-BR translation catalogs and a refreshed .pot.

= 0.7.7 =
* Fixed a 0.7.6 regression: the content-link localization also rewrote the language switcher's own default-language link (which is unprefixed by design), so visitors couldn't switch back to the source language. The plugin's own UI and `translate="no"` regions are now excluded from link localization.

= 0.7.6 =
* Internal links hardcoded in post content (root-relative like `/about/`, or absolute with the site's own domain — common on migrated sites) are now localized on translated pages, so visitors no longer drop back into the source language on the first click. System paths (`/wp-*`), direct file links and URLs already carrying a language prefix are left untouched. Disable with the `trrocket_localize_content_links` filter.

= 0.7.5 =
* Fixed: explicit switcher colors from the customizer are now emitted with !important, so dropdown menu items stay readable inside colored theme headers (theme anchor palettes could override them, causing white-on-white text).

= 0.7.4 =
* Fixed: URL localization could double the language prefix (e.g. /it/it/) on canonical, feed and oEmbed links when an already-localized URL passed through home_url() again. A re-entrancy guard now leaves localized URLs untouched.

= 0.7.3 =
* Replaced every external-service URL in the readme and admin with its canonical, redirect-free address (DeepL privacy/service pages, OpenAI privacy page, translaterocket.com privacy/donate pages) so all declared links resolve directly.

= 0.7.2 =
* Security & code-quality hardening (WordPress.org review): every admin and front-end output is now late-escaped with `wp_kses()` and an allowlist covering the plugin's SVG flags, icons and controls; the switcher's colour and size settings are validated at save time (hex colours, numeric-only sizes) so a value can never inject CSS; and the bulk string/translation deletes build their `IN()`/`LIKE` clauses through `$wpdb->prepare()`.
* Fixed a dead Author URI and "Get expert help" link.

= 0.7.1 =
* Visual editor: the "original text" preview no longer showed the source in the target language. The plugin's own dynamic-content translator was rewriting the editor's source preview; the popup is now marked so neither it nor the browser touches the editor chrome, so the source text always stays in the original language while you edit.

= 0.7.0 =
* Every feature that ships is now free and fully functional: removed the optional target-language cap and removed the background auto-translation of new content. On-request AI translation is unchanged — translate a page, or a whole language, on demand with your own provider key. A `trrocket_page_collected` action is available for add-ons.
* Removed the switcher "Custom CSS" field (arbitrary CSS insertion); style the switcher with the built-in colour/shape options or your theme's stylesheet.
* Admin CSS and JavaScript are now enqueued with the WordPress functions (`wp_enqueue_*`, `wp_add_inline_script`, `wp_add_inline_style`) instead of being printed inline.
* Removed the deprecated `libxml_disable_entity_loader()` call and the no-longer-needed `load_plugin_textdomain()` (WordPress loads translations automatically).
* The front-end page buffer is now closed explicitly on shutdown.

= 0.6.4 =
* TranslatePress import: strings are now imported in decoded form. TranslatePress stores its segments with HTML entities ("Bed &amp;amp; Breakfast", "pi&amp;ugrave;"), which never matched the page text and could print entities literally — those strings stayed untranslated after an import. Found while migrating a real site.

= 0.6.3 =
* Fixed: on a translated URL, a page whose slug merely starts with the language code 404ed (e.g. /de/demo/, /it/items/, /es/estimate/) — WordPress stripped the language prefix a second time from the slug itself while parsing the request. Found by translating our own site.

= 0.6.2 =
* Editing a translation now also clears your host / CDN page cache: on a cache flush the plugin signals the common cache and CDN plugins (Breeze, WP Rocket, W3 Total Cache, WP Super Cache, WP Fastest Cache, LiteSpeed, SG Optimizer, Cache Enabler, Nginx Helper, WP-Optimize) plus a `trrocket_flush_caches` action for anything else — so a changed translation appears right away instead of waiting out their TTL.
* Admin: the language picker now keeps a small gap between rows when it wraps, so the buttons don't touch on sites with many languages.
* Passes Plugin Check with zero errors.

= 0.6.1 =
* Provider fallback chain: give two or more AI providers a priority on the AI page and bulk / automatic translation tries them in order — when one runs out of credit or its key is refused, the next one takes over automatically, so a big job can span several accounts without stopping. Free, in the core.
* Serialize translated pages from the document root node, fixing a literal "&#9662;" (and other characters) showing up inside CSS on translated pages.

= 0.6.0 =
* Huge-site engine ("huge-safe"): on sites with more than ~20,000 detected strings the plugin stops loading the whole language map per request and switches to indexed per-page batch lookups — constant memory, whether your site has 500 strings or 500,000. Small sites keep the exact same fast path as before.
* New indexed text hash on stored strings (schema v3, migrated automatically in the background).
* WooCommerce, forms, dynamic-content, page-copy and term-slug translation all use the new size-aware lookups.
* Translation memory now saves you money before every AI call: a text already translated anywhere on the site (another page, an image alt, an interface string, a glossary term) is copied for free instead of being sent to the API again, and duplicate texts in one batch are only paid once.
* New "Saved by reuse" counter on the AI page: characters and strings translated for free, with a cost estimate at your provider's list prices.

= 0.5.5 =
* Admin: a pink "Support the project" link in the navigation — the plugin is 100% free; supporters get priority help.

= 0.5.4 =
* Dropdown switcher: reliable tap-to-close on touch devices (sticky hover/focus no longer keeps the menu open).
* Scroll switcher: the current language now wears a single thin neutral ring.
* Sharper admin banner: the logo wordmark gained a crisp shadow for readability.

= 0.5.3 =
* Scroll switcher: the current language starts centred in the strip and is highlighted with a tinted pill and brand-coloured ring.

= 0.5.2 =
* Branding: ™ added to the TranslateRocket logos and product name across the plugin UI.

= 0.5.1 =
* Security (full code audit): password-protected pages now keep their password form when an independent copy is active (the copy also inherits the password); CSV export shields cells against spreadsheet formula injection (and the import transparently removes the shield); the language-redirect cookie is now HttpOnly/Secure/SameSite=Lax.
* SEO: the multilingual sitemap no longer advertises hreflang alternates for languages a page is excluded from (redirect / 404 / custom message).

= 0.5.0 =
* **SEO panel in the visual editor:** a new "SEO" button in the editor toolbar opens the translated URL slug, the SEO title and the meta description for the current language — edit search-facing fields right from the live page.
* Switcher: new per-profile **"Menu background (dropdown)"** option to style the dropdown panel (with backdrop blur) independently from the toggle.
* Switcher customizer: the live preview now renders the dropdown toggle and menu items with exactly the front-end styling (colours, radius, shadow) — no more mismatched items.

= 0.4.0 =
* New optional **"Powered by TranslateRocket"** badge (with logo). Off by default; enable it in Settings to show it in the footer, or place it anywhere with the `[translaterocket_poweredby]` shortcode.

= 0.3.0 =
* **Dynamic content translation:** text added by JavaScript after the page loads — cookie/consent banners (Complianz, CookieYes, Borlabs…), popups, AJAX-loaded results — is now translated automatically, reusing your existing translations (no extra AI calls). Better out-of-the-box compatibility with the most common plugins.

= 0.2.0 =
* New **Scrollable bar** switcher layout: a horizontal, fixed-width switcher with ‹ › arrows (hover an arrow to scroll continuously) — ideal when you have many languages. Width configurable in px or %.
* Visual editor: toggle any string between the numbered-block view and raw **HTML editing**.
* New **Translate page** button in the editor toolbar — auto-translate the whole page in one click (your AI provider or free Google), or use the guided copy & paste.
* Language switcher arrow visibility and sizing fixes.

= 0.1.0 =
* Initial public release: detection engine, per-page and in-editor translators, on-page visual editor (click-to-edit in a draggable popup, with Prev/Next, progress and skip-translated), free Google Translate links and copy & paste, AI providers (DeepL, OpenAI, Gemini, Anthropic, Google), translated slugs and hreflang, theme/plugin interface strings, per-page language visibility, TranslatePress & Polylang import, language switcher (shortcode, block, widget) with SVG flags, 36 built-in languages, Italian UI translation.
