Any WordPress site · WooCommerce · v0.8.6

Translate
once. Serve
from a file.

Content is translated in the background the moment you publish it. Visitors read a dictionary compiled to a file — no API on the request, no translation triggered by traffic.

/en/ English /es/ Español /de/ Deutsch /fr/ Français /it/ Italiano /nl/ Nederlands /pt-br/ Português do Brasil /ja/ 日本語 /sv/ Svenska /pl/ Polski
Any WordPress site

Not only
for stores.

WooCommerce is optional. A blog, a company site, a portfolio or a shop — if it runs on WordPress, it is translated the same way: in the background, and served from a file.

  • Blogs
  • Company sites
  • Portfolios
  • Magazines
  • Landing pages
  • Online stores

Pages & posts

Every page and post, with their categories and tags. Publish or edit and the new text is translated a few seconds later.

  • pt Sobre nós
  • en About us
  • es Sobre nosotros

Menus

The header, the footer and every menu built in Appearance → Menus.

  • pt Início Loja Contactos
  • en Home Shop Contact
  • es Inicio Tienda Contacto

Your theme

Buttons, header and footer texts — read from one page of each template, so the theme’s own words are covered too.

  • pt Ler mais
  • en Read more
  • es Leer más

SEO

hreflang on every page and the language prefix kept in the canonical and og:url, so no translation is dropped as duplicate.

<link rel="canonical" href="https://example.com/en/about/">
<link rel="alternate" hreflang="pt" href="https://example.com/about/">
<link rel="alternate" hreflang="en" href="https://example.com/en/about/">
<link rel="alternate" hreflang="es" href="https://example.com/es/about/">
<meta property="og:url" content="https://example.com/en/about/">

Search & dates

A visitor searching in their language finds results, and dates follow each language’s own format.

  • pt 12 de setembro de 2026
  • en September 12, 2026
  • es 12 de septiembre de 2026

Sitemap

No second sitemap to submit. The translated pages are added to the sitemap Google already knows — one entry per page and language, each listing all its language versions. Without an SEO plugin, WordPress’s own sitemap gets one sitemap per language.

<url>
  <loc>https://example.com/en/about/</loc>
  <xhtml:link rel="alternate" hreflang="pt" href="https://example.com/about/"/>
  <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/about/"/>
  <xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/about/"/>
</url>

Page cache

Each language is its own URL, cached apart and purged after every translation.

  • pt /about/ Cached
  • en /en/about/ Cached
  • es /es/about/ Cached
Works with

SEO & sitemaps

  • Yoast SEO
  • Rank Math
  • Slim SEO
  • WordPress sitemap
Works with

Page cache

  • WP-Optimize
  • LiteSpeed Cache
  • WP Rocket
  • W3 Total Cache
Works with

Store

  • WooCommerce
  • Official WordPress & WooCommerce translation packs
Running WooCommerce? The cart, the checkout and the order emails are covered too
Built for stores too

The parts
others leave
in English.

The cart, the checkout, the notices — where an untranslated string hurts most, at the moment someone is spending money. Covered in three different ways, because they come from three different places.

Cart & checkout

Covered three ways

Labels come from WooCommerce's own human-reviewed pack. Product and category names come from the dictionary, through the Store API. Shipping and payment names are collected straight from WooCommerce.

Automatic

And it stays that way

Whatever is published or saved is translated on its own. The whole site is checked again once a week and after every theme or plugin update. A reviewed translation is never overwritten by the machine again.

SEO

The sitemap Google knows

One URL per language with hreflang alternates, inside the Yoast SEO, Rank Math or Slim SEO sitemap. The canonical keeps the language prefix, so nothing is dropped as duplicate.

Strings

Review by hand

Every translation listed with a "Where" column for context. Fix one and it is yours for good. Failed strings are marked and never block the rest.

Recording mode

Catch what a crawl can’t

A cart with items, a checkout returning errors, an invalid coupon. Browse as an admin with ?pht_record=1 and they are recorded, at no cost to any visitor.

Updates

Signed, from PixelHunter

New versions show up in Plugins → Installed Plugins like any other. Every package is signed with an ed25519 key; a swapped package is refused.

Page cache

Purged for you

Each language is its own URL, so any cache stores it apart. After a translation the changed pages are purged in WP-Optimize, LiteSpeed Cache, WP Rocket and W3 Total Cache. Two hooks cover the rest.

Search

Works in every language

A visitor in English searching for "jacket" finds "Casaco": the plugin looks up the source term. The theme and the search engine never know.

Glossary & tone

Your words, your voice

Brand names and fixed terms stay as written — one rule per line. A sentence or two about the brand's tone travels with every request. Anything inside translate="no" or <address> is left alone.

Order emails · WooCommerce

The email arrives in the buyer’s language.

Someone buys in English. WooCommerce fires "Your order has been paid" — and the plugin sends it in English: subject, heading, product names, shipping and payment method, the date, the text you wrote for the footer. The order itself is saved in the store’s language, so the admin, the invoices and the reports read one language.

What the store wrotept-PT · the store
Subject: A sua encomenda #1042 foi paga
A sua encomenda foi paga

Olá Emma, obrigado pela sua compra. Já estamos a preparar a encomenda.

Vestido midi em linho — Preto, M× 149,00 €
Blusa de seda — Marfim, S× 278,00 €
Total132,00 €
Envio: Taxa fixa · 5,00 €Pagamento: Cartão de crédito12 de setembro de 2026

Loja Mariana · Rua das Flores 12, Lisboa · Responda a este email para falar connosco.

What the buyer receivesen · the buyer
Subject: Your order #1042 has been paid
Your order has been paid

Hi Emma, thank you for your purchase. We are already preparing your order.

Linen midi dress — Black, M× 149,00 €
Silk blouse — Ivory, S× 278,00 €
Total132,00 €
Shipping: Flat rate · 5,00 €Payment: Credit cardSeptember 12, 2026

Loja Mariana · Rua das Flores 12, Lisboa · Reply to this email to reach us.

Every email after the purchase

Paid, completed, refunded, a note from the shop — in the language of the purchase, from the subject to the footer.

Your own words, translated once

Subject, heading, additional content and footer you wrote in WooCommerce → Emails go through the dictionary. Review them by hand in Strings.

Labels for free, dates done right

"Subtotal", "Shipping", "Payment method" come from WooCommerce's human-reviewed pack. The date uses each language's own format — no "9 de September de 2026".

The shop reads one language

Orders are saved in the source language with the language of the purchase in _pht_lang. Emails to the administrator stay in the store's language.

Every order status

Processing Paid Completed Refunded Note from the shop All in the buyer's language Admin emails · store language
The language switcher

Any corner.
Four shapes.

Nothing for the theme to fight. Four kilobytes of CSS, only on the pages where it shows. Three shapes are plain links with zero JavaScript. Colours, size, corners and shadow are set with a live preview that warns under 4.5:1 — and every value is a CSS variable, so a theme can restyle it without !important.

AppearanceSwitcher tab
Box#ffffff
Language#1a1a1a
Current#1a1a1a
Hover#dcdcde
Text size14px
Corners8px
Shadowsoft
Contrast 16.1:1 — passes WCAG AA. The panel warns the moment a text colour falls under 4.5:1.

Where it appears

Modes
01Automatic — floats in the corner you pick, nothing to touch in the theme. It also shows in the cart and the checkout, where a visitor in the wrong language needs a way back.
02Manual — place it yourself with [pht_switcher] or pht_switcher() in a template. The floating one steps aside on that page; there are never two.
03Off — hidden. Names or codes, with or without emoji flags, is a switch either way.

Suggestion bar

Optional
01A visitor whose browser speaks another language sees a small bar at the top offering their version.
02It suggests, it never redirects. Redirecting by browser language breaks the page cache, and Google advises against it.
03It shows once. Choosing or closing answers for good. On translated pages the browser's own "Translate this page" offer is silenced — theirs on top of ours reads worse.
How it works

One
separation.

Translation happens in the background. Serving is read-only. It is the model Shopify uses for Translate & Adapt — and the opposite of plugins that translate HTML on demand and pay again for every new page a visitor opens.

Translation time

Background
01Text is read straight from the database — products, categories, pages, menus, shop settings — plus one page of each template.
02Only what is missing goes to the PixelHunter translation service, several batches at once. A whole shop takes under a minute.
03The dictionary is compiled to a PHP file inside uploads/. A product you publish is translated a few seconds later.

Serving time

Read-only
01The language prefix is stripped before the WordPress router runs — /en/shop/ resolves like /shop/. No rewrite rules.
02The dictionary sits in OPcache. Serving a translated page costs neither a query nor an HTTP request.
03HTML goes through the core WP_HTML_Processor. With an empty dictionary the output is byte for byte the input.
cost = 38 ms + 0.12 ms × replacement linear · measured on the heaviest page of a real store · 262 KB · 719 replacements
Set-up

Four steps. One button.

There is no API account to set up and nothing to configure: the translation API holds its own key. A glossary and a brand tone are optional, under Settings.

1 Languages

Pick the source, add the targets

Each target language gets its own URL prefix — /en/, /es/. The panel installs the missing WordPress and WooCommerce translation packs with one click.

2 License

Paste the key

Best in wp-config.php as PHT_LICENSE_KEY: not in the database, not in an export, not editable from the admin. One key serves every site of your plan.

3 Dashboard

Translate the site

One button reads the whole site and sends what is missing, with a progress bar. Close the page — the rest carries on in the background.

4 Strings

Review what matters

Filter by status, search, fix by hand. From then on, whatever you publish is translated on its own.

Pricing

Pay for text.
Not traffic.

Every visit is free — only new or edited text is sent to be translated. Each character counts once per target language, and unused characters roll over while the subscription is active. Yearly plans cost ten months.

Billing period
Currency
Free trial
Free
no card, once
30,000 characters, once
1 site
Try it free
Starter
$5/mo
billed monthly
$50/yr
12 months for the price of 10
300,000 characters a month
1 site
3,600,000 characters a year, all at the start
1 site
Subscribe Subscribe
Pro Most stores
$12/mo
billed monthly
$120/yr
12 months for the price of 10
1,500,000 characters a month
up to 5 sites on one key
18,000,000 characters a year, all at the start
up to 5 sites on one key
Subscribe Subscribe
Agency
$29/mo
billed monthly
$290/yr
12 months for the price of 10
6,000,000 characters a month
up to 25 sites on one key
72,000,000 characters a year, all at the start
up to 25 sites on one key
Subscribe Subscribe

Questions about taxes, how characters are counted or changing plan? Read the plans guide in the documentation.

Straight answers

What it does. What it doesn’t.

01

Do I need an API account?

No. The plugin only talks to the PixelHunter translation API, which holds its own key — you only need the license key.

02

Do I need WooCommerce?

No. WooCommerce is optional: the plugin translates any WordPress site — pages, posts, menus, categories and the texts of your theme. When there is a store, the cart, the checkout and the order emails are covered too.

03

Are the translated pages in my sitemap?

Yes. There is no second sitemap to submit: the translated pages are added to the one you already have. With Yoast SEO, Rank Math or Slim SEO each page gets one entry per language, with all its versions as hreflang alternates; without an SEO plugin, WordPress’s own sitemap gets one sitemap per language.

04

Which plugins does it work with?

Yoast SEO, Rank Math and Slim SEO for canonicals and sitemaps; WP-Optimize, LiteSpeed Cache, WP Rocket and W3 Total Cache for page cache purging; and WooCommerce, with its official translation packs. Any other page cache can be connected through two hooks.

05

Are URL slugs translated?

No, on purpose. Only the prefix changes: /en/produto/blusas/ keeps the source slug. Each language still has its own address, with a canonical that keeps the prefix and hreflang to every other version, so Google sees language versions — never duplicate content. And a link never breaks when a translation is later fixed.

06

Does it slow my site down?

In the source language, 0 ms. On translated pages the dictionary is read from OPcache; a host page cache serves each language once per URL per TTL.

07

“Subtotal”, “Proceed to checkout”?

They come from the official WooCommerce translation pack — reviewed by humans, at no API cost. The panel says which packs are missing and installs them.

08

Do emails to the shop change?

No. Emails to the administrator stay in the store’s language; only the customer’s emails go out in the language of the purchase.

09

Requirements?

WordPress 6.7 or later and PHP 8.1 or later. No build step, no jQuery, no runtime dependencies.

10

What happens when the characters run out?

Translation pauses and retries every hour. Nothing is lost: pending texts wait for the next period, and the site keeps serving everything already translated. Need more? Change plan in My account: a new key for the new plan arrives by email, and translation resumes once it is pasted on your sites.

11

And if I cancel?

The key works until the end of the paid period. After that the site still serves every translation it has — only new text stops being translated.

12

Does staging count as a site?

Yes. Translate on the live site, or free a slot in My account → Activations while you work on the copy. The free trial is once per site and does not accept disposable emails.

13

What is not translated?

URL slugs, anything inside <script> — including SEO plugins' JSON-LD — and customer emails not tied to an order, which go out in the store's language. Each sentence has one translation across the whole site.

For developers

Three functions. Three filters. Two actions.

Current language
<?php if ( 'en' === pht_current_language() ) : ?>
  <p>Free shipping to the UK.</p>
<?php endif; ?>
Switcher, by hand
[pht_switcher show_label="no" class="mine"]

<?php pht_switcher( [ 'style' => 'dropdown' ] ); ?>
Any page cache
add_action( 'pht_purge_urls', function ( $urls ) {
  foreach ( $urls as $url ) my_cache_purge( $url );
} );

Publish.
Read it in
every language.

30,000 characters, one site, no card. The key arrives by email after checkout.