= 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.

= Earlier releases =

Versions 0.1.0 to 0.10.0 are listed in changelog.txt, shipped with the
plugin and readable at
https://plugins.svn.wordpress.org/translate-rocket/trunk/changelog.txt
