- language metadata
- BCP 47
- internationalization
BCP 47 language tags: label transcription input without guessing
A plain-language guide to BCP 47 tags, scripts, regions, and private-use subtags for safer transcription and subtitle metadata.
A language name such as “Chinese,” “Portuguese,” or “Serbian” may be too broad for a transcription job. A flag is worse: countries are not languages, and many languages cross borders.
BCP 47 language tags provide a stable interchange syntax for identifying human languages. A tag can be as short as en, or add the distinctions a workflow genuinely needs, such as pt-BR, zh-Hans, or sr-Latn.
The key rule is restraint: use the shortest valid tag that describes the content accurately. More subtags do not make metadata more precise when the underlying information is unknown.
Read a tag from left to right
RFC 5646 defines the structure and semantics of language tags. Common pieces include:
- a primary language subtag, such as
en,ja, orar; - an optional script subtag, such as
Latn,Cyrl, orHans; - an optional region subtag, such as
US,GB, orBR; - optional variants, extensions, or private-use subtags for narrower cases.
Examples:
enidentifies English without asserting a region;en-GBidentifies English associated with the United Kingdom;zh-Hansidentifies Chinese written with the Simplified script;sr-Latnidentifies Serbian written in the Latin script;es-419uses the UN M49 region code for Latin America and the Caribbean.
Language tags are not filenames or provider model IDs. Store the standardized tag as content metadata, then map it to a provider’s current capability code at the integration boundary.
Do not infer what you do not know
If a user selects “Portuguese” and gives no regional information, pt is more honest than guessing pt-BR or pt-PT. If script matters and is known, record it. If it does not matter or is not known, omit it.
Avoid deriving a language from:
- a user’s IP address or account country;
- the flag they clicked in an unrelated locale selector;
- the file extension;
- the language of the surrounding webpage;
- a provider’s default model.
Automatic language detection can be a useful hint, but it is a probabilistic result. Keep the detected value, confidence, model version, and user confirmation conceptually separate from user-supplied metadata.
Validate against the IANA registry
The IANA Language Subtag Registry is the operational registry referenced by RFC 5646. It records language, script, region, variant, and related subtags, including deprecated values and preferred replacements.
A production validator should:
- parse the complete tag rather than checking only the first two letters;
- verify registered subtags and their allowed positions;
- recognize grandfathered and private-use forms where the product permits them;
- preserve the original valid tag or apply a documented canonicalization policy;
- reject malformed tags before they enter URLs, provider requests, or exports.
BCP 47 matching is its own operation. A valid request for es-MX does not prove that a provider with an es model supports every regional feature. Capability fallback must be explicit and tested.
Casing is for readability
Language tags are compared without case sensitivity, but a conventional presentation makes their parts easier to inspect:
- language in lowercase:
en; - script in title case:
Latn; - region letters in uppercase:
US; - variants in lowercase.
Normalize casing at a boundary if consistency helps, but do not treat EN-us as a different language from en-US solely because of letter case.
Separate four product concepts
Transcription interfaces often collapse distinct ideas into one “language” field. Keep these concepts separate:
- Content language: the BCP 47 tag that describes the recording or transcript.
- Interface locale: the language and conventions used by the product UI.
- Provider capability: the model, code, and features an ASR provider currently supports.
- Translation target: the requested language or locale for a new derived artifact.
For example, an English interface can transcribe Arabic audio and translate the result into French. None of those settings should overwrite another.
Design the selector around names, not flags
A language picker should show a recognizable language name, its native name when helpful, and the standardized tag when ambiguity remains. Search can match aliases, but the stored value should be the validated tag.
When a distinction affects provider behavior, explain it in words: “Portuguese (Brazil)” and “Portuguese (Portugal)” are clearer than two flags. When a generic model is the only supported option, say so instead of presenting unsupported regional precision.
Accurate metadata cannot make a model understand a language it does not support. It can prevent silent mismatches, make exports interoperable, and leave an auditable record of what the user requested.