Drafts
Translation proposals — manual or AI — that land as a reviewable diff before they ever reach a profile.
Translations don't go straight into a profile. They land first as a draft: a set of proposed values for one profile, attributable to a source (you, an AI run, an imported XLIFF file) and reviewable inline. Merging promotes the draft into the profile. Publishing — a separate, deliberate step — pushes the profile to KV and the CDN.
This separation is the single most important guardrail in Shipeasy Translations. AI translations are good but not perfect; merging without review is how you ship "Confirmer" as a button label that overflows on mobile in three locales for two weeks before anyone notices.
The shipeasy i18n translate ... invocations on this page are the planned CLI surface — they
aren't shipped yet. Today the same workflows run through Shipeasy Translations → Drafts in the
dashboard, and through the i18n_translate_draft MCP tool when you'd rather drive it from Claude.
Use shipeasy i18n scan / i18n push / i18n publish for the parts that are wired today.
Lifecycle
created → (review) → merged → (publish) → published
└→ abandonedA profile can have one open draft per source at a time. Multiple sources in parallel are fine — you can have an AI draft and a manual draft running concurrently and pick keys from each. On merge, the dashboard reconciles overlaps row-by-row.
Creating a draft
From AI
The most common path. The CLI calls Anthropic Claude (using your project's API key — see Translations for setup) and creates a draft with proposed values for every key missing from the target profile.
shipeasy i18n translate --profile fr --aiExisting values are not overwritten unless you pass --reflow. Filter by chunk for a smaller, faster run:
shipeasy i18n translate --profile fr --ai --chunk checkoutThe dashboard streams progress live — keys translated, keys remaining, current cost, ETA.
From an import
If you already have translations (a contractor delivered a file, you exported from another tool):
# Flat JSON map: { "key": "value" }
shipeasy i18n translate --profile fr --import ./french-translations.json
# XLIFF 2.1 (industry-standard exchange format)
shipeasy i18n translate --profile fr --import ./fr.xlf
# CSV with key,value columns
shipeasy i18n translate --profile fr --import ./fr.csvThe import becomes a draft, not a direct merge. You still review it; row-by-row attribution shows the import file as the source.
Manual entry
In the dashboard, Shipeasy Translations → Drafts → New opens an empty draft for the chosen profile. You can paste keys and values, or use the inline editor. Useful for quick fixes ("change the FR CTA from 'Régler' to 'Payer'") that don't merit a full AI run.
Reviewing a draft
Open Shipeasy Translations → Drafts → fr. You see a four-column view:
| Source (en) | Current (fr) | Proposed (draft) | Decision |
|---|---|---|---|
| Welcome back | Bon retour | Bienvenue à nouveau | ✓ Approve |
| Pay | (empty) | Régler | ✗ Reject (edit inline) |
| 3 unread messages | 3 messages non lus | 3 messages non lus | — No change |
| Sign out | (empty) | Se déconnecter | ✓ Approve |
You can:
- Approve a row — the value moves to the merged set.
- Edit inline — fix the AI's output before approving (saves the edit alongside the AI proposal for audit).
- Reject — keep the existing profile value (or fall back to source).
- Mark for translator — flag a row that needs human attention before merge; appears in the per-user worklist of anyone with the
translatorrole. - Comment — start a thread on a row. Useful for "is this the right register?" or "ask legal about this".
The dashboard shows the source value, any description on the key, the AI's confidence (when sourced from AI), and an optional back-translation for sanity-checking locales you don't speak.
Bulk actions
Most drafts are reviewable in under twenty minutes because the bulk actions handle the boring 80%:
- Approve all unchanged — every row whose proposal matches the current value.
- Approve all high-confidence — every AI proposal above a confidence threshold (default 0.85).
- Approve chunk — every row in a single chunk after a quick scroll.
- Filter to "needs attention" — rows with low confidence, length-budget warnings, or unresolved comments.
Keyboard shortcuts: j/k next/prev row, a approve, r reject, e edit, c comment, ? show all.
RBAC
Roles control what each teammate can do on a draft:
Translator→
Can edit, approve, and reject rows on drafts for the locales they're scoped to. Cannot merge, cannot publish, cannot create profiles.
Reviewer→
All translator powers, plus can merge drafts into the profile. Cannot publish to
:prod profiles — that needs admin.
Admin→
All reviewer powers, plus publish to any locale, create/delete profiles, manage roles, configure tone and glossary.
Translator scope is set per-locale: a translator scoped to fr sees only fr:* drafts; one scoped to fr,es,it sees those three. The CLI honors the same scoping when authenticated with a personal token.
Merging
When you're satisfied, click Merge draft. Approved values are promoted into the profile. The draft moves to merged.
Merging does not publish. This is deliberate — merging is "I've reviewed; the profile is internally correct". Publishing is "this version is going to users". Decoupling them lets you stage a complete merge (often dozens of keys at once) and publish atomically:
shipeasy i18n publish --profile frYou can also auto-publish on merge in Project → Shipeasy Translations → Settings → Auto-publish on merge if you trust the review step entirely. Most teams turn this on for :dev and :staging but leave :prod manual.
Side-by-side review and back-translation
For target locales you don't speak, the dashboard offers a back-translation view. The AI translates the proposed value back to the source locale; you compare the back-translation against the original. Mismatches usually mean the proposed translation drifted.
Original: "Pay"
Proposed (FR): "Régler"
Back-translation: "To settle / pay (a bill)" → ✓ acceptable
Original: "Sign out"
Proposed (DE): "Anmelden"
Back-translation: "Sign in" → ✗ reject — this is wrongBack-translation is on-demand (one extra Claude call per row) so it doesn't bloat the default review cost.
Conflict resolution
If two open drafts touch the same key, the latest merge wins; the other draft's row for that key is marked conflicted and you re-decide on next review. The dashboard surfaces conflicts at the top of the draft view with a banner — no one can merge a conflicted draft without acknowledging it.
A typical scenario: a translator is hand-editing fr while a nightly cron runs --ai on new keys. The cron's draft has a row for checkout.cta_label; the translator's draft also touched it. On merge of one, the other gets flagged.
CI integration
For teams running translation contracts, the --ci mode generates a draft, prints a summary, and exits non-zero if the draft is empty (nothing to translate) — handy in scheduled cron jobs that translate any new keys nightly.
shipeasy i18n translate --profile fr --ai --ciA common GitHub Actions setup:
# .github/workflows/i18n-nightly.yml
on:
schedule: [{ cron: "0 4 * * *" }]
workflow_dispatch:
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm i -g @shipeasy/cli
- run: shipeasy i18n scan ./src --rewrite --profile en:prod
- run: shipeasy i18n publish --profile fr:prod
env: { SHIPEASY_CLI_TOKEN: ${{ secrets.SHIPEASY_CLI_TOKEN }} }For the AI translation draft step, kick the dashboard flow from
shipeasy login on a developer machine or via the
i18n_translate_draft MCP tool — the CLI subcommand for AI
translations isn't shipped today, so the CI step above is "scan + push
- publish", not "translate + publish".
Discarding and abandoning
shipeasy i18n drafts abandon <draft-id>Or from the dashboard. Abandoning frees the profile for a new draft. The abandoned values remain in the dashboard's history for 30 days in case you change your mind — shipeasy i18n drafts restore <draft-id> brings it back as a new open draft.
Drafts cost nothing to create or abandon. The dashboard is built around the assumption that you'll have several in flight at once: an AI draft for new keys, a human draft for a marketing rewrite, an XLIFF import from a contractor. Pick rows from each, abandon the rest.
Tune how Claude writes.
Drafts are only as good as the prompt behind them. Configure tone, glossary, and per-locale overrides so the AI sounds like your brand from the first run.