Back in 2021 a German e-commerce client came to Seahawk with a brief that basically said: "We need our WooCommerce store in English, French, and Polish. By March." It was November. And the budget for human translation was, let's say, ambitious in the wrong direction. We'd used Google Translate's API on a couple of projects before and the output was, honestly, embarrassing for anything beyond button labels. So I went looking.
That's when I properly sat down with DeepL. I'd seen it mentioned in a few developer threads but hadn't taken it seriously. Biggest mistake I made in that half-decade. Once I ran the same product descriptions through both APIs and showed the client side-by-side output, there was no contest. We shipped the German store in three languages before Christmas, the client added Dutch six months later without breaking a sweat, and that project is still one I point to when people ask what good API integration looks like.
This post is about the practical reality of wiring DeepL into a website. Not the marketing copy. The actual implementation decisions, the cost model, the gotchas, and what I'd tell my past self before starting.
Why DeepL Actually Beats the Alternatives
I'll be blunt: for European languages, DeepL is in a different tier. The model was trained heavily on the Europarl corpus and other high-quality parallel texts, and you feel it immediately in output for German, French, Spanish, Italian, Dutch, Polish, and Portuguese. The sentence structure feels considered rather than word-swapped.
Google Translate's API (v2 and v3) is cheaper and covers more languages. 133 vs DeepL's 29 supported languages as of mid-2024. If you need Swahili or Bengali, DeepL isn't your answer. Full stop. But if your client is expanding across the EU or into Japan (DeepL does Japanese remarkably well), you'd be doing them a disservice by defaulting to Google out of habit.
The other thing nobody talks about enough: DeepL's formality parameter. You can set formality=more or formality=less and the API will adjust the register of the output accordingly. That matters enormously for German, where du/Sie isn't a minor stylistic choice. A DTC fashion brand wants a different register than a B2B SaaS company. I've had clients notice this distinction in their translated copy without me even pointing it out.
Understanding the Cost Model Before You Commit
DeepL charges per character translated. The free API plan (DeepL API Free) gives you 500,000 characters per month. That sounds like a lot until you're translating a WooCommerce catalogue with 800 products and long descriptions.
The Pro plan starts at around $6.99/month for 500,000 characters and scales from there. For most agency projects I run, the cost sits somewhere between $15 and $60 a month depending on catalogue size and update frequency. Compare that to professional human translation rates (typically £0.10 to £0.18 per word in the UK market) and the API pays for itself inside the first 200 words.
One thing that burned me early on: HTML handling. DeepL can receive raw HTML and will attempt to preserve tags rather than translate them. You pass tag_handling=html in your request. But if your HTML is malformed or your product descriptions contain inline scripts (looking at you, some WooCommerce plugins), the output can get mangled. I learned to sanitise content before it hits the API, not after.
The Two Integration Paths: WordPress and Custom Builds
WordPress Sites
For WordPress, the most direct path I've used is the WPML integration. WPML has a native DeepL connector built into their Translation Management module. You authorise your DeepL API key inside WPML's settings, select which content types to auto-translate, and it handles the queue. It's not magic, a human review step is still worth building into the workflow, but for a 300-page site it saves weeks.
The alternative is Polylang Pro with the DeepL add-on. Slightly cheaper licensing, a bit less polished on the translation management side. I used Polylang on a French restaurant group site last year. Fine for that scale. But for anything with custom post types and ACF fields, WPML handles the edge cases better in my experience.
If you're building headless WordPress (Gatsby or Next.js front-end pulling from WP via GraphQL), you'll want to call the DeepL API directly from your build pipeline or a serverless function. Don't try to shim it through a plugin in that architecture. It won't scale cleanly.
Custom / Non-WordPress Builds
Here's where it gets interesting. DeepL publishes official client libraries for Python, Node.js, PHP, Ruby.NET, and Java. The Node.js library is solid. I've used it on a Next.js project where we cached translations in Redis to avoid redundant API calls on repeated strings.
A basic Node.js call looks like this:
`` const deepl = require('deepl-node'); const translator = new deepl.Translator('YOUR_AUTH_KEY'); const result = await translator.translateText('Hello, world', null, 'fr'); console.log(result.text); // 'Bonjour le monde' ``
Simple. The real architecture question is caching. You do not want to hit the API on every page load. Store translations in your database or a cache layer (Redis works well, even a simple JSON file works for small sites). Invalidate the cache when source content changes. That's it. Most of the complexity is in cache invalidation logic, not the API call itself.
Handling Placeholders and Dynamic Content
This tripped up one of my developers at Seahawk on a SaaS project where the UI strings contained variables like {{user_name}} and {{count}}. Feed those raw to DeepL and it'll sometimes translate the variable names. Not ideal when {{nombre_de_usuario}} ends up in your Spanish UI.
The fix: use DeepL's XML handling and wrap your placeholders in ignore tags before sending.
`` <deepl:ignore>{{user_name}}</deepl:ignore> has {{count}} new messages. ``
Set tag_handling=xml and ignore_tags=deepl:ignore in your request parameters. The API preserves anything inside those tags. This is documented in DeepL's API reference but it's easy to miss on a first read. Cost me about three hours of debugging on that SaaS project. Hopefully it costs you none.
Building a Sensible Review Workflow
Machine translation is not a publishing button. I'd never recommend shipping DeepL output directly to a live site without at least one native speaker pass, particularly for anything customer-facing. But the workflow doesn't have to be painful.
Here's what I set up for most client projects:
- Run initial translation through DeepL API.
- Push output to a staging translation table (in WPML this is automatic; in custom builds I write to a
translationsDB table with astatuscolumn defaulting topending). - Send a link to the client's in-market reviewer (often the client's own local team or a freelancer from ProZ).
- Reviewer edits directly in the CMS or a simple review interface I build.
- Status flips to
approved, content goes live. - Lock the string so it doesn't get overwritten on the next API sync.
That last step matters. I've seen setups where a content update on the source language triggers a full re-translation and wipes out all the human corrections. Build the lock mechanism before you build anything else.
SEO Considerations for Multilingual Sites
Translated content alone won't rank. You need hreflang tags in your HTML <head> for every language variant, and they need to be correct. A mismatched hreflang setup can actually suppress your international pages in search results. I've seen this happen to a client who had a beautiful translated French site sitting in obscurity for four months because someone got the language codes wrong ( fr-FR vs fr).
Beyond hreflang: translated URLs. Ideally you want slugs translated too, not /fr/how-to-cook-pasta but /fr/comment-cuire-les-pates. DeepL can translate slugs but you'll want to run them through a slug formatter afterwards (lowercase, hyphens, remove special characters). WPML does this automatically. In custom builds, handle it manually.
And metadata. Page titles, meta descriptions, alt text on images. All of it needs translation treatment. I run metadata through DeepL separately in the pipeline, not as part of the body content batch. Easier to control character limits that way.
Where DeepL Falls Short
Honest answer: brand-specific terminology. DeepL doesn't know what your client calls their product features. If a fintech client uses "Smart Vault" as a product name, DeepL will translate it. Every time.
The fix is DeepL's glossary feature. You define term pairs via the API (source term, target term, language pair) and attach the glossary ID to your translation requests. That Smart Vault becomes "Smart Vault" in every language because you've told it to. You can manage glossaries programmatically or via DeepL's dashboard. I set up glossaries as part of every project kickoff now. It takes 20 minutes and prevents a category of errors that would otherwise cost hours to catch in review.
The other honest limitation: DeepL's language coverage. 29 languages is genuinely restrictive if your client has ambitions beyond Europe and East Asia. If you need Arabic, you're looking at a hybrid approach: DeepL for the European languages, Google Cloud Translation or Microsoft Azure Translator for everything else, unified behind a single internal API layer that routes by language pair. Annoying to build once. Very convenient to maintain.
FAQ
Is the DeepL API free to use?
There's a free tier with 500,000 characters per month, which is generous for testing and small projects. The free plan requires a credit card on file but won't charge you unless you exceed the limit or upgrade. For production sites with any real traffic or content volume, you'll almost certainly want a paid plan. The Pro tiers start at around $6.99/month and scale by character usage.
Can I use DeepL with WordPress without a plugin?
Technically yes. You can call the REST API directly from a WordPress custom plugin or functions.php using wp_remote_post(). But unless you enjoy reinventing wheels, the WPML or Polylang integrations handle the translation queue, string syncing, and content locking for you. I'd only go custom-API-direct in WordPress if you have a very specific architecture reason.
How accurate is DeepL compared to human translation?
For European languages, DeepL regularly scores within a few percentage points of human translation on BLEU score benchmarks. Practically speaking: good enough for product descriptions and UI strings, not good enough for legal documents, creative copy, or anything where tone and cultural nuance are the whole point. Always build a human review step into client projects.
Does DeepL translation affect SEO?
Machine-translated content that hasn't been reviewed can be flagged as low-quality by search engines, particularly if it reads unnaturally. Google has stated they don't penalise auto-translated content per se, but thin or garbled content will underperform. My rule: review before indexing, not after.
What's the best way to handle translation updates when source content changes?
Track a content hash (MD5 of the source string is fine) alongside each translation in your database. When source content is updated, the hash changes, which flags the translation as stale. Your pipeline then re-translates only the changed strings rather than the whole page. This keeps API costs down and prevents unnecessary churn on strings that were already human-reviewed.
---
The DeepL API is one of those tools that genuinely changed how I scope multilingual projects. Not because it removes the need for human judgement, but because it shifts the work from tedious first-draft translation to meaningful editorial review. That's a better use of everyone's time, including your client's budget. Wire it up carefully, cache aggressively, build the review step in from day one, and it'll serve you well.