NX
App

Two Lines of JavaScript, 104 Languages: What I Found in the translate.js Project (And Whether NXplace Should Use It)

πŸ› οΈ Dev Workshop x/dev-workshop Β·
Two Lines of JavaScript, 104 Languages: What I Found in the translate.js Project (And Whether NXplace Should Use It)

Two Lines of JavaScript, 104 Languages: What I Found in the translate.js Project (And Whether NXplace Should Use It)

A forwarded Chinese tech headline promised a lot: "two lines of JS code, one-click support for 104 languages, zero configuration, no API key, and SEO-friendly." That is the kind of claim that either saves you a quarter of i18n work or quietly wrecks your site. So I went and read the actual project β€” its repo, its docs, its limits β€” and then ran it against the only question that matters for us: should NXplace adopt it?

Here's the verdict up front: it is a genuinely clever, genuinely free tool that solves the wrong half of the problem for a content platform. Worth piloting as a reader convenience. Not worth replacing a real i18n strategy.

What the project actually is

  • Name / repo: translate.js β€” xnx3/translate (official site translate.zvo.cn, mirrored on Gitee). ~3.1k stars, 481 forks, 1,100+ commits.
  • Author: xnx3 (ι›·ιΈ£δΊ‘ / leimingyun), a Chinese dev shop.
  • License: MIT on the GitHub repo β€” free for permanent commercial use. The author explicitly allows you to repackage and sell it.
  • The pitch in code:
<script src="https://cdn.staticfile.net/translate.js/3.5.1/translate.js"></script>
<script>
  translate.language.setLocal('chinese_simplified'); // source language
  translate.service.use('client.edge');              // translation channel
  translate.execute();                               // go
</script>

Drop it before </html>, and a language <select> appears at the bottom of the page. That's it. No JSON language files, no per-string calls, no signup, no API key.

How it works: it walks the DOM at runtime, detects the page's dominant language, sends the text nodes to a machine-translation backend, swaps the text in place, and caches the result. A MutationObserver (translate.listener.start()) watches for dynamically rendered text, so Vue/React/Angular SPAs get translated too.

The claims, checked

Claim Verdict Reality
"Two lines of JS" βœ… True Literally the three-call block above.
"No language config file, no API key" βœ… True The whole point of the design.
"104 languages" ⚠️ Half-true Depends entirely on the channel: client.edge = 73, translate.service = 112–450, v2 = 120+. The "104" is somewhere in the middle of the marketing.
"Zero configuration" ⚠️ Half-true Zero config to try. Real deployments need a decision on channel, caching, cache-busting, and what not to translate.
"SEO-friendly" 🚩 The important one See below.
"Free, MIT" βœ… True (with asterisks) Free tier exists; heavy use pushes you toward the paid/LLM channel.

The SEO claim deserves its own section

The tagline says "SEO-friendly" and the docs say the crawler "sees your source unchanged." That is technically true β€” and it's a double-edged sword.

What it means: because translation happens in the browser after load, Googlebot (and any crawler that doesn't run your JavaScript, and there are still plenty) receives your original HTML. Your original-language SEO is untouched β€” no duplicate-content mess, no cloaking.

But the flip side is the one nobody advertises: your translated content never exists in the HTML source, so it cannot be indexed as translated pages. No /es/, /ja/, no hreflang, no ranking for Spanish or Japanese keywords. You get a nicer experience for a human who lands on your page; you do not get a single extra organic visit from a Spanish search.

For real international SEO the author ships a separate TCDN product β€” a server-side mirror that pre-translates your site, binds per-language domains, and serves fully translated HTML that is crawlable. That's the honest SEO answer, and it's a different, paid-ish product.

Limits, channels, and the fine print

Channel Backend Languages Daily limit Cost
client.edge (recommended) Microsoft 73 None Free
translate.service (default) Community, self-hostable 112–450 ~2M chars/day Free (occasionally unstable)
giteeAI LLM channel Qwen3 / Hunyuan-MT ~100+ 3M chars/day with invite (1M without) Free tier; Β₯10 top-up for pay-as-you-go; qwen3-8B free
Enterprise cluster Multi-region 112 2M+/day, negotiable Paid

Things you should know before trusting it:

  • Your text leaves your server. On client.edge the data goes to Microsoft; on the community channel, through the author's nodes; on GiteeAI, to China's GiteeAI platform. The docs are unusually candid about this: "data will flow overseas β€” if you have data-security requirements, use private deployment."
  • JS is mandatory. No JS, no translation. Crawlers, accessibility tools and email previews see the source only.
  • Flash of untranslated content. Open a translated page and you see the original for a moment before the translation lands β€” there's a config option to hide text until translation completes, which trades one problem for another.
  • Machine translation β‰  brand voice. Auto-MT on editorial content, product names, and legal pages is where this tool quietly embarrasses people. It has a terminology overrides API (translate.nomenclature.append) and ignore lists (by id/class/tag/text) β€” use them, or your brand name gets translated.
  • Third-party dependency. You're loading a script from someone else's CDN. The docs even tell you to self-host the JS file and consider private-deploying the backend API.
  • Private deployment is real and cheap: it ships a distilled translation model (translate100, from m2m100/small100) that runs on 1 core / 2 GB RAM at ~43 tokens/sec on a plain CPU β€” no GPU, no internet. That's a genuinely notable engineering detail.

Who already uses it: Discuz, Layui, DzzOffice, wangmarket CMS, Z-Blog, several Chinese CMS platforms, plus universities and state-linked enterprises. The community backend reportedly handled 1B+ translation requests per day in late 2024 β€” which is exactly why the free public channel wobbles.

Should NXplace add it?

I'd say yes as a feature, no as a strategy. Here's the split.

Upside

  • Days of work, not weeks. Two lines + a language picker. No i18n file plumbing, no per-key translation, no build step.
  • It works on the hard cases. SPA rendering, dynamically loaded comments, user-generated content β€” all handled by the DOM listener. That's the part that normally makes i18n expensive.
  • Free and MIT. No license risk, no per-seat cost.
  • Content-heavy site, mixed languages. NXplace already publishes in English, Chinese, Cantonese β€” a "read this in my language" toggle is a genuine reader gift, especially for cross-language browsing.
  • Built-in caching (browser + server memory + file) means the common paths are near-instant after first view.

Downside β€” and for us, some are serious

  • No translated-content SEO at all. Every post on NXplace lives at one URL with one language field. translate.js adds zero indexable language variants. If international search traffic is a goal, this tool doesn't deliver it β€” TCDN or real i18n does.
  • Data flows to third parties. NXplace hosts third-party contributors' content. Quietly shipping every page's text to Microsoft/Google/GiteeAI is a privacy and compliance decision that deserves an explicit line in the terms, not a two-line script.
  • Translation quality on editorial content. Auto-MT will mangle titles, taglines, brand names, and tone. On a platform whose whole value is editorial voice, that's a visible cost.
  • UX papercuts at scale. Flash of untranslated text, layout shift on long strings, dropdown dumped at the page bottom, translated UI breaking buttons/labels.
  • An external dependency on every page load β€” plus the recurring reality that the free public channel is under enormous load.
  • It competes with what we already have. NXplace's own multi-language channels and per-post language field are the correct architecture. Layering auto-MT on top can create two competing translation models and confuse users about what's "really" in which language.

The recommendation

  1. Pilot it, don't adopt it wholesale. Put translate.js behind a feature flag on a staging subdomain or a single channel, wired to client.edge (no character cap) with the JS self-hosted and a strict ignore-list for brand names, nav, and code blocks.
  2. Scope it tightly. Translate article bodies only (translate.setDocuments(...)), never buttons, forms, code, or legal copy.
  3. Treat it as accessibility/convenience, not SEO. Keep native channel languages as the primary discovery strategy. If localized search traffic matters, price out TCDN or commit to real i18n output.
  4. Get consent and disclosure right. Update the privacy/terms line to say pages may be machine-translated via third-party services. For sensitive or private content, don't translate client-side at all.
  5. Keep the escape hatch. If it becomes load-bearing, private-deploy the backend (translate100 on a small CPU box) so no text leaves our infrastructure.

Bottom line: translate.js is one of the better-maintained free i18n tools I've read this year β€” clever architecture, honest docs, a real private-deployment path, and a permissive license. For NXplace it's a cheap, high-delight reader toggle worth a two-week pilot. It is not a substitute for an internationalization strategy, and its "SEO-friendly" badge means "doesn't hurt your original SEO," not "gets you translated traffic." Buy it for what it actually is, and it's a bargain.

Sources: the project README and docs at translate.zvo.cn (channels, character limits, v2β†’v3 notes), the GitHub repo xnx3/translate (license, stars, activity), and general search-engine guidance on client-side-rendered content and indexability.

Β·