Translate without
leaving Obsidian

Edit PO/Gettext files entry-by-entry, validate plurals, and convert to XLIFF, ARB, JSON, YAML, or ICU — all from a vault you already know.

A kawaii octopus translator and red panda exchanging greetings مرحبا 안녕 Olá Hej! Ciao 안녕!
MSGID · EN
“Hello, world!”
MSGSTR · EN
“Hello, world!”
PO ↔ XLIFF PO ↔ ARB PO ↔ JSON PO ↔ YAML PO ↔ ICU plural forms msgctxt fuzzy flag c-format obsolete entries project mode BRAT support CodeMirror TypeScript
What's inside

A localization workspace, not a glorified text editor.

01

Dual-mode editing

Browse entries as a structured list — ID, status, and context at a glance. Click any entry to open the editor panel. Switch to raw PO source for direct access.

02

Smart filtering

Filter by status, format flag, comment, or context. Find the 12 fuzzy entries hiding in a 4,000-entry catalog in seconds.

03

Focus mode

Step through entries one by one with keyboard shortcuts. No distractions, no mouse — pure kilometer translation mode for translators who need to ship.

04

Entry validation

Flag fuzzy entries, missing translations, and move obsolete strings out of your active catalog — keep your PO files clean without leaving Obsidian.

05

Plurals done right

Pick a language when creating a PO file and the correct Plural-Forms header is written automatically from CLDR rules. First-class support for msgid_plural with all required forms per locale. Integrity checks catch missing or mismatched forms before you ship.

06

Stats & export panel

Track progress per language — translated, fuzzy, obsolete counts — then export to any format from the sidebar.

07

Multi-format conversion

Round-trip to XLIFF, ARB, ARB Enhanced, JSON, YAML, and ICU MessageFormat without losing flags or comments.

08

Project mode

Treat a folder of PO files as one project. Switch locales, compare progress, sync settings across the set.

09

Fast on large catalogs

No lag on thousands of entries. The list renders instantly whether you're editing 50 strings or 50,000 — your vault stays responsive.

10

Quick actions

Define labeled buttons that apply flags or translator comments in one click. Assign a PO flag (e.g. #, c-format), a comment, and a color. Buttons appear in the editor panel — tag entries without breaking your translation flow.

11

Configurable to your workflow

Dock the editor panel top, bottom, left, or right. Define custom placeholder patterns (%s, %(key)s, %1$d) that render as clickable chips in translation cells. Auto-check headers on open or keep it on demand.

?

Need a feature?

Missing something? An Idea for better UX? Open a feature request on GitHub — describe your use case and we’ll take a look.

Request a feature →
In action

What it looks like inside Obsidian.

fr.po — PO Editor
STATISTICS
68% 67 31 4 98 KEYS REF: JA · Japanese
Center Complete Image
Download Add Text
Running Pause Available
Succeeded Visible
Center Forward Download
Star Failed Pending
Japanese MSGID Download Add Text ダウンロードテキストを追加する
French
Télécharger Ajouter Texte
Translator comment…
2 / 98 · 37 ch
PROJECT PROGRESS
58%
Translated1,580
Untranslated1,138
Fuzzy247
Languages27
FR
68%
JA
66%
AR
51%
+24 more languages…
The shape of a PO file

Plain text, structured.

Every entry has context, source, translation, optional plurals, flags, and translator notes. PO Editor renders all of it as a structured form — but the underlying file stays a perfectly clean .po.

msgctxt Disambiguates same-text-different-meaning entries
msgid_plural CLDR plural forms with full integrity checks
#, fuzzy Mark entries that need a human review
#: source.ts:42 Jump straight to where the string lives in code
# Translator: claude · 2 hours ago
#: src/views/inbox.tsx:91
msgctxt "inbox"
msgid "You have one unread message"
msgid_plural "You have {count} unread messages"
msgstr[0] "Tu as un message non lu"
msgstr[1] "Tu as {count} messages non lus"

#, fuzzy, c-format
#: src/net/client.ts:77
msgctxt "errors"
msgid "Could not connect to %s"
msgstr "Connexion à %s impossible"
How it works

Four steps from blank to shipped.

01

Open or create

Click any .po file in the file explorer to open it in the editor, or use the PO ribbon button to create a new file. Pick a language and an output folder.

⌘P
02

Edit in list view

Click any entry in the list to open the editor panel — set msgstr, toggle flags, add comments. Or jump to raw mode for direct source editing.

03

Validate

Run "Validate PO File" to scan for empty msgstr, fuzzy entries, and obsolete strings. Flag issues before committing.

04

Convert & export

Round-trip to XLIFF for translators, ARB for Flutter, JSON/YAML for web stacks, or ICU for runtime use.

Formats

Eight formats. One source.

Comments, flags, and source references survive every conversion (when you want them to).

Gettext POT
.pot
R/W
XLIFF
.xliff
PO ↔
Flutter ARB
.arb
PO ↔
ARB Enhanced
.arb · with metadata
PO ↔
JSON
.json
PO ↔
YAML
.yaml
PO ↔
ICU MessageFormat
.json
PO ↔
Installation

Three ways in.

Desktop only · Obsidian 0.15.0+

01

Open Obsidian

Settings → Community plugins → Browse

02

Search

"PO Editor"

03

Click Install

then Enable

01

Install BRAT

from Community plugins

02

Open BRAT

Settings → Add Beta Plugin

03

Enter the repo

Kodaskills/obsidian-po-editor

01

Download release

main.js, manifest.json, styles.css

02

Copy to plugin folder

<vault>/.obsidian/plugins/po-editor/

03

Reload Obsidian

and enable the plugin

Roadmap

What's next.

v0.1 shipped List view + raw editor, 8 formats, validation, plurals, fuzzy auto-suggest
v0.2 next Translation memory, glossary
v0.3 planned LLM-powered drafts, terminology consistency checks
v0.4 planned Mobile-friendly layout, collaborative editing notes
FAQ

Things people ask.

Not yet — PO Editor is desktop-only (isDesktopOnly: true in the manifest). Mobile support is on the roadmap once the core feature set settles.

No. Everything happens inside Obsidian, on files in your vault. The plugin reads and writes PO files (and any conversions) to your chosen output directory.

Yes. Round-trip your PO files to XLIFF for sending to translators, ARB for Flutter, JSON/YAML/ICU for web, then back to PO. Comments, flags, and references survive every hop (when configured).

Obsolete entries are strings no longer in your source but still present in the PO file. Instead of deleting them, the plugin lets you move them to the obsolete section — they're preserved for reference but excluded from active translation counts.

Yes. msgid_plural with all required forms per language, plus integrity checks that warn when the count of msgstr[] doesn't match the language's expected plural categories.

Most actions live in the command palette (⌘P / Ctrl+P). You can also bind any editor action via the keyMapping setting — no restart needed.

Yes — a focus workflow is built in. Filter the entry list to untranslated entries, then click the fullscreen button in the editor panel header to expand it to overlay mode. Type your translation, then press Alt+↓ to save and jump to the next entry instantly. Alt+↑ goes back. The command palette also has “Navigate to next untranslated entry” if you want keyboard-only flow without touching the mouse.

Translate at home,
in your vault.

Free, MIT-licensed, and crafted with care by Kodaskills.