Translations
Localized labels and AI-assisted translations — discovered from your code, live worldwide in seconds.
Localize your product, as easy as asking Claude.
Shipeasy plugs into your codebase, finds every user-facing string, and ships translations that read like a human wrote them — because Claude did. From npm install to a fully translated build in five minutes.
Shipeasy Translations treats translations like configuration. You discover keys from source, store them on the project, generate translations (manually or via AI), review, and publish. New copy goes live worldwide in seconds — no redeploy.
The 5-minute path
From hardcoded English to 12 languages
~5 minutesInstall the loader
A 1.4kB gzipped script tag — patched into your framework's entry file automatically.
Codemod + push keys
JSX/TSX strings get rewritten to t("key") calls. Vue, Svelte, plain HTML get listed
for manual wrap.
AI draft, you approve, publish
Claude drafts every missing key with your tone and glossary. Review in the dashboard, click publish.
What Shipeasy Translations does
Auto-discover keys→
Scan your repo for t("hero.title") calls — or let the codemod find raw English
strings and rewrite them automatically.
Per-locale profiles→
en, fr, de:staging. Each profile is a manifest of keys
and values you can publish, diff and revert.
Drafts & inline review→
Translations live as drafts before they ship. AI-generated or hand-written — both reviewable inline by anyone with edit access.
AI translations with brand voice→
Anthropic Claude generates a draft for missing keys. Your tone and glossary are read on every call — never marketing-speak unless you ask.
How copy gets to the user
Codemod or scan
shipeasy i18n scan ./src (or the MCP i18n_codemod_apply) discovers strings and rewrites them as t("key"). Skipped strings (dynamic interpolations, rich HTML) land in i18n-codemod-review.json for manual review.
Push keys
Discovered keys are pushed to a source profile (e.g. en). Each key has a value, an optional description, and a stable hash so re-scans don't shuffle ordering.
Translate
Create a target profile (fr). Run i18n translate --ai to draft missing values. Claude reads your tone and glossary on every call. Review side-by-side in the dashboard.
Publish
i18n publish --profile fr ships the merged label set worldwide. Single-key edits don't invalidate the whole bundle — only the relevant chunk is updated.
Loader fetches the active locale
A small <script> in your HTML fetches the right chunks for the active locale. Zero JS dependencies. Sub-millisecond from anywhere.
Quick install
shipeasy login
shipeasy i18n install-loader --profile en # injects the script tag
shipeasy i18n scan ./src --rewrite # discovers & rewrites t("…") calls
shipeasy i18n push --profile en
shipeasy i18n profiles create --name fr --locale fr
# AI draft + review happen in the dashboard or via the i18n_translate_draft
# MCP tool — the CLI subcommand for this is on the roadmap.
shipeasy i18n publish --profile frDetailed walkthrough at Quickstart.
Shipeasy Translations works with your own Anthropic API key (zero markup, zero data retention) or the hosted plan with a generous free tier. Switch any time in the project settings — translations stay in your project either way.
Configure
Translation settings live on the profile (one per locale, e.g.
en:prod, fr:prod). Configure source language, targets, tone, glossary
terms, and AI provider in the dashboard under Translations → Profiles
→ Settings. The same values can be edited via the
Admin API.
A declarative shipeasy.config.ts is on the roadmap — until then, the
profile is the authoritative configuration surface.
Settings reference
"en".pt-BR) when register matters.{ kind: "anthropic", apiKey: env.ANTHROPIC_KEY } for BYOK.Use it in your app
Shipeasy Translations ships through the same client SDK as flags and
experiments. Call i18n.t(key, fallback) anywhere — the active locale is
picked from your loader script (or the cookie / URL param you configure),
and translations come from the chunked bundle the loader fetches.
// app/(marketing)/page.tsx (Server Component or "use client" — both work)
import { i18n } from "@shipeasy/sdk/client";
export default function Page() {
return (
<section>
<h1>{i18n.t("landing.hero.title", "Localize, as easy as asking Claude.")}</h1>
<p>{i18n.t("landing.hero.sub", "Ship in 12 languages without ever leaving your editor.")}</p>
</section>
);
}The English fallback string is the SOURCE OF TRUTH — shipeasy i18n scan
picks it up and pushes it to the en profile, and the AI draft uses it as
the prompt to translate from. The key (landing.hero.title) is what the
runtime looks up in the published chunk. Pre-launch you can ship without
ever opening the dashboard — fallbacks render until the chunk is up.
This is for static UI strings the scanner can extract at build time. For UGC (chat messages, reviews, support tickets) you need a streaming runtime translation endpoint — that surface isn't shipped yet.
Why a separate product
You could store labels as a dynamic JSON config — and for tiny apps, you should. Shipeasy Translations exists because real-world i18n hits problems configs aren't built for:
- Volume: tens of thousands of keys. One JSON blob is unworkable.
- Workflow: translators are not engineers and shouldn't need access to flag tooling.
- Discovery: keys come and go with code; manual sync drifts immediately.
- Performance: chunking + lazy loading by route is critical at the upper end.
- Stats: you want to know which keys are unused, which translations are stale, which locales lag behind.
Shipeasy Translations handles all of that and exposes a dead-simple SDK for the runtime side.
Stop reading. Start localizing.
The fastest way to feel Shipeasy Translations is to run it on your own repo. Five thousand strings on us — no card, no email gate, runs in your terminal.