Skip to content

Translation Editor

The editor lays out one block per translation key. Inside each block, languages are arranged according to the current view mode. The source language (typically en) is read-only — it’s your reference. Every other cell is editable.

The table is virtualized with TanStack Virtual, so repos with thousands of keys scroll smoothly.

Pick a view mode from the filter sidebar.

ModeLayout
oneEvery language stacks vertically inside the row block as `LANG
twoSource is pinned to the left as a sticky column; targets stack on the right. Best when you want to keep the source value visible while scanning translations.
responsiveUses the two shape at lg: (1024px) and above; collapses to one shape on narrower viewports.

Each cell carries a lang attribute (mapped from the project’s locale folders to BCP-47), so the browser’s spell-checker uses the right dictionary for each language.


Every editable cell renders a <textarea> from the moment it mounts — there’s no read-mode/edit-mode swap. Click in and start typing.

ActionShortcut
Commit the buffer to a draftCmd/Ctrl + Enter or blur (click/tab away)
Revert the in-flight buffer to baselineEscape
Insert a newlineEnter
Move to the next cellTab (browser’s natural tab order)

Cells with unsaved drafts show a small Modified dot. A per-cell revert button appears on those cells; click it to drop just that cell’s draft and restore the baseline value.


The filter sidebar on the left holds every way to narrow the table:

  • Search — match against the key path or any value.
  • Status chipsAll / Translated / Untranslated / Modified, each with a live count.
  • Namespace selector — single-select; pick which translation namespace (file) to focus on.
  • Target-language selector — choose which target languages are visible.
  • Show all languages toggle — quickly flip between focused targets and the full set.
  • View-mode selectorone / two / responsive.

The sidebar has a top-level toggle that swaps between Filter mode and Bulk Actions mode. Bulk Actions hosts batch operations like AI translation runs (see AI Suggestions). The toggle resets to Filter on every shell mount — it’s session-only.


Unsaved edits are stored as drafts, scoped per (repo, branch, project) in the app’s local settings (editorDrafts).

  • Drafts survive branch switches. If you start editing on feature-a, switch to main, and switch back, your feature-a drafts are still there.
  • The unsaved-drafts dialog that appears when you switch branches is purely informational (“You have N unsaved drafts on <branch> — continue?”). It does not destroy anything; the previous branch’s drafts stay where they are.
  • The per-cell revert button drops a single cell’s draft.
  • The toolbar’s Discard button opens a confirmation dialog and, on confirm, drops every unsaved draft and every pending deletion in the current (repo, branch, project) scope.

Saving opens a dialog from the toolbar’s Save button. The dialog covers commit message, push, and PR creation in one flow. There is no Cmd+S shortcut — see the PR Flow guide for the full walkthrough.


A right-hand sidebar appears when you select a cell. It’s collapsed by default; the toggle in the editor remembers your choice via editorViewState.detailsCollapsed.

When expanded, it shows:

  • GitHub blame link — jumps straight to the source-language line in GitHub for the selected key.
  • AI translation section with a Suggest button (or Regenerate after a prior result) — see AI Suggestions for the full flow.

When you’re reviewing a PR, additional cues appear in the table itself — see PR Mode.