Skip to content
screenjson

For localisation teams

ScreenJSON for Localisation Teams

One file, every language. How ScreenJSON turns translation from a parallel-files problem into a first-class property of the document.

Last updated January 2026

The parallel-files problem

Every localisation team has felt this. A feature film ships, subtitles get commissioned in 24 languages, dubbing scripts in 6. Somewhere along the way, the production team made three edits to the English master that didn’t propagate evenly across all 30 derivative files. By the time anyone notices, three of the Italian subtitles disagree with the English, the Japanese dub is five seconds out of sync, and the localisation vendor is asking for the v4 final final FINAL script by EOD.

ScreenJSON ends that workflow. It doesn’t improve the management of parallel files; it makes parallel files unnecessary.

One file, every language

Every user-facing textual field in a ScreenJSON document is a map keyed by BCP 47 language tag, not a plain string:

{
  "text": {
    "en": "We have ninety seconds.",
    "fr": "Nous avons quatre-vingt-dix secondes.",
    "ja": "九十秒しかない。",
    "es": "Tenemos noventa segundos.",
    "de": "Wir haben neunzig Sekunden."
  }
}

One line of dialogue, five languages. The viewer picks one at render time. The exporter picks one at export time. The whole screenplay is a single artifact.

Where translations actually live

At the root: title, logline. On the cover: title again, with optional extra free text. On every scene: the slugline’s desc. On every element: the text field for action, dialogue, parentheticals, shots, transitions, and general. On every note: the note text itself.

Character fields are usefully bilingual-or-more: desc is language-keyed, and the canonical name (the uppercase cue used in formatting) stays a single string because cue conventions are fixed per language. Alternate spellings for other languages go in aliases.

The translation workflow in practice

A realistic path looks like:

  1. Author in the source language. Final Draft, Fountain, whatever — export to ScreenJSON.
  2. Snapshot. Tag the document with a revision label like "en-final" and record it in revisions.
  3. Project. Emit a translation-ready bundle: every element’s text.en, keyed by element UUID, in a flat file your TMS can ingest. The JSON structure means this is a one-liner.
  4. Round-trip. Your TMS returns a bundle of translated strings, keyed by element UUID. Merge them back into the same ScreenJSON document under the target language key. No file duplication; no parallel-file drift.
  5. Render in any supported language with screenjson export --lang fr or by setting viewer.lang = 'fr'.

Because every element has a stable UUID, that merge is deterministic and idempotent: you can re-import the same translation bundle a dozen times and end up with the same document. You can also diff “what translations changed between build 14 and build 15” with ordinary JSON diff tooling.

On right-to-left languages

Each text field can be accompanied by a dir flag (ltr or rtl) on the element. A screenplay with Arabic or Hebrew dialogue can intermix directions without forcing the whole document into one direction. The viewer respects dir per element.

On continuity and dubbing

Dubbing scripts care about things a literal translation doesn’t: syllable count, lip-sync shape, reaction beats. ScreenJSON doesn’t do that work for you — that’s the dubber’s craft — but it gives you a clean place to record the dubbed line as an alternate text key, and it lets you record the dubber’s parentheticals as real parenthetical elements rather than inline notation.

A common convention is to use region-qualified tags for dub-specific lines: fr for a literal translation, fr-FR-dub for the lip-synced dubbing version.

On subtitle timing

ScreenJSON doesn’t carry frame-accurate timing — that belongs in a subtitle format (SRT, TTML, WebVTT), and should be generated downstream from the locked ScreenJSON. But because every dialogue element has a UUID, the link back from a subtitle line to its source screenplay line is trivial: keep the element UUID as a sidecar in your subtitle file and you can round-trip between the two.

Multi-language title pages

The cover’s title field is a language map too. A screenplay released internationally can carry “The Heist” (English), “Le Braquage” (French), and “強奪” (Japanese) on the same cover, with the viewer picking the right label for the right locale.

On machine translation

Nothing in the schema prevents you from running a first-pass machine translation on every text field, keyed by source language, to seed a target-language column. You’d then hand that seed to a human translator in your TMS for review.

Because every string is keyed by element UUID, you can track exactly which fields have been reviewed, which are still machine-seeded, and which haven’t been touched yet — with any metadata discipline you like in the meta block on each element.

Encryption and vendor trust

Pre-release translations are sensitive. AES-256 encryption of text runs (leaving structure, UUIDs, and revision metadata visible) lets you hand an encrypted document to a translation vendor’s ingestion pipeline — for routing, estimation, billing — without letting that pipeline see any dialogue. The vendor’s human translators decrypt locally, translate, re-encrypt, return.

Next