Shipeasy
Translations

Drafts

Translation proposals — manual or AI — that land as a reviewable diff before they ever reach a profile.

ReferenceOn this page · 8 min readUpdated · May 3, 2026Works with · Next, Vite, Remix, Astro, Expo

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.

CLI examples below are roadmap

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
                  └→ abandoned
Field
Type
Description
openrequired
state
Draft exists, nothing merged yet. Reviewers can approve, edit, reject rows.
mergedrequired
state
Approved values were promoted into the profile. Still unpublished — runtime sees nothing yet.
publishedrequired
state
The profile (with these values) was published to KV and the CDN. Visible to users.
abandoned
state ?
Discarded without merging. Auto-deleted after 30 days. Recoverable until then.

A 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 --ai

Existing values are not overwritten unless you pass --reflow. Filter by chunk for a smaller, faster run:

shipeasy i18n translate --profile fr --ai --chunk checkout

The 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.csv

The 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 backBon retourBienvenue à nouveau✓ Approve
Pay(empty)Régler✗ Reject (edit inline)
3 unread messages3 messages non lus3 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 translator role.
  • 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 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 fr

You 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 wrong

Back-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 --ci

A 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 are cheap — make many

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.

NEXT

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.

Scan repo
$shipeasy i18n scan ./src
Publish merged
$shipeasy i18n publish --profile fr
Side-by-side review · RBAC · back-translation
Was this page helpful?✎ Edit on GitHub

On this page