The texts folder and file structure
Every resource pack, behavior pack, and world template can have its own `texts/` directory right at the root of the pack, alongside `manifest.json`. For in-game content like item names, block names, entity names, and chat messages, your translations belong in the Resource Pack (`RP/texts/`). Behavior Pack text files (`BP/texts/`) are only needed if you want to translate the name and description of the behavior pack itself inside the world settings menu.
Inside the `texts/` folder, you need two types of files: a `languages.json` registry file and one or more `.lang` files (such as `en_US.lang` for American English or `es_MX.lang` for Mexican Spanish). The `languages.json` file is a simple JSON array of locale codes that tells Minecraft which `.lang` files actually exist in your pack. If you add a `.lang` file but forget to list its locale code in `languages.json`, the game will ignore that language file completely.
[
"en_US",
"en_GB",
"es_MX"
]Writing .lang files
A `.lang` file is a plain text file saved with UTF-8 encoding (without a Byte Order Mark). Each line maps a translation key to its displayed text using a single `=` sign, with no spaces around the equals sign. Everything to the left of the `=` is the key, and everything to the right up to the end of the line (or a comment marker) is the value shown to the player.
Comments in `.lang` files start with `##`. If you want to put a comment on the same line after a translation value, you must separate the value and the `##` with a literal Tab character, not spaces. If you use spaces before `##`, the game treats the hashes and your note as part of the visible string. You can also use `%1`, `%2`, or `%s` as positional placeholders when a string is fed dynamic values from commands or scripts.
## Pack Manifest
pack.name=Crystal Caverns Resource Pack
pack.description=Textures and translations for Crystal Caverns.
## Custom Items and Blocks
item.caverns:amethyst_shard=Amethyst Shard ## Inline comment after a Tab
tile.caverns:amethyst_block.name=Block of Amethyst
## Custom Entities
entity.caverns:crystal_golem.name=Crystal Golem
item.spawn_egg.entity.caverns:crystal_golem.name=Spawn Crystal Golem
## Custom Chat Messages
chat.caverns.welcome=Welcome to the caverns, %1!Standard translation keys
When you create custom content without specifying a custom display name component, Minecraft automatically generates a default translation key based on the `identifier` in your JSON file. If that default key exists in your `.lang` file, the game displays your translated text automatically.
Modern items and blocks can also override this automatic key using the `minecraft:display_name` component in their Behavior Pack JSON, which lets you point to any custom key string you prefer (or even pass a literal string directly, though using a key in `.lang` is better practice). The table below shows the default key patterns the engine looks for when you do not override them.
| Content Type | Default Key Pattern | Notes |
|---|---|---|
| Custom Block | tile.<namespace>:<id>.name | Used when `minecraft:display_name` is omitted on a block. |
| Custom Item (Component-based) | item.<namespace>:<id> | Newer item format keys often omit the `.name` suffix unless specified in `minecraft:display_name`. |
| Custom Item (Legacy) | item.<namespace>:<id>.name | Older format versions append `.name` automatically. |
| Entity | entity.<namespace>:<id>.name | Shown in death messages, name tags, and `/say` output. |
| Spawn Egg | item.spawn_egg.entity.<namespace>:<id>.name | Controls the inventory hover name of an entity's auto-generated spawn egg. |
Overriding names with minecraft:display_name
In current behavior pack schemas for items and blocks, you can explicitly set the translation key using the `minecraft:display_name` component. Instead of guessing whether the engine expects a `.name` suffix at the end of your item key, you pass your exact key into the component's `value` field.
When the game renders the item or block name, it checks if the string in `value` matches a key in the active `.lang` file. If it finds a match, it shows the translated text; if it does not find a match, it prints the raw `value` string as a fallback.
{
"format_version": "1.20.50",
"minecraft:item": {
"description": {
"identifier": "caverns:amethyst_pickaxe",
"menu_category": {
"category": "equipment"
}
},
"components": {
"minecraft:icon": "amethyst_pickaxe",
"minecraft:display_name": {
"value": "item.caverns:amethyst_pickaxe.name"
}
}
}
}Using RawText in commands and manifests
Outside of automatic item and block labels, you can reference your `.lang` keys inside `manifest.json` and inside commands like `/tellraw` or `/titleraw`. In `manifest.json`, put your key name (`pack.name` and `pack.description`) directly into the `name` and `description` fields of the `header` object.
In commands and Script API methods that accept RawMessage objects, use the `translate` property instead of `text`. If your `.lang` entry includes placeholders like `%1` or `%2`, pass a `with` array alongside `translate` to fill those slots dynamically. The game resolves the translation on each player's client using whichever language they have selected in their settings.
{
"format_version": 2,
"header": {
"name": "pack.name",
"description": "pack.description",
"uuid": "8f4a7b12-3c9e-4d2a-9b1f-5e6c7d8a9b0c",
"version": [1, 0, 0],
"min_engine_version": [1, 20, 50]
},
"modules": [
{
"type": "resources",
"uuid": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
"version": [1, 0, 0]
}
]
}Formatting codes and line breaks
You can style text inside `.lang` files and RawText strings using the section sign (`§`) followed by a single formatting code character. Because `.lang` files are UTF-8 encoded, you type or paste the literal `§` character directly into the `.lang` line (do not use `\u00a7` inside `.lang` files, as `.lang` parsers do not unescape Unicode sequences; `\u00a7` only works inside `.json` files). Always reset formatting with `§r` when switching styles so colors do not bleed into Bold or Italic text.
To create a multi-line string inside a `.lang` value—for example, in a custom dialogue box or chat output—use the literal two-character sequence `%1` or `\n` depending on where the string is rendered. In most UI and chat contexts, `\n` forces a line break inside a single `.lang` entry.
| Code | What it does | Notes |
|---|---|---|
| §0 - §9, §a - §f | Standard 16 text colors | `§a` is green, `§c` is red, `§e` is yellow, `§f` is white. |
| §l | Bold text | Apply after the color code, as applying a color resets bold. |
| §o | Italic text | Item names renamed on an anvil use this by default. |
| §k | Obfuscated (garbled) text | Continuously cycles random characters of the same width. |
| §r | Reset formatting | Restores default color and clears bold, italic, and obfuscation. |
Which versions this applies to
Applies to all modern Minecraft Bedrock versions (1.16.0 through 1.21+). The `.lang` file format, `languages.json`, and `RawText` translation keys are completely stable and do not require any experimental toggles.
When it does not work
| What you see | Why | The fix |
|---|---|---|
| In-game items or blocks show raw strings like `tile.caverns:amethyst_block.name` or `item.caverns:shard.name` instead of their proper names. | Either you placed your `.lang` file in the Behavior Pack instead of the Resource Pack, you added spaces around the `=` sign (`key = value`), or your game client is set to a language (like `en_GB`) that does not have a corresponding `.lang` file and cannot fall back because `en_US` is missing from `RP/texts/languages.json`. | Move your `texts/` folder to the Resource Pack (`RP/texts/`), remove any spaces immediately before or after the `=` sign in your `.lang` file, and verify `en_US` is listed in `RP/texts/languages.json` as the universal fallback. |
| Comments at the end of a line (`## my note`) show up inside the player's inventory hover text. | You separated the translation value and the `##` comment marker using regular spaces instead of a Tab character. | Delete the spaces between the end of your text and `##`, and press the `Tab` key once (or move the `##` comment onto its own dedicated line). |
| Section sign colors (`§a`) display a weird character like `§a` in-game. | Your text editor saved `en_US.lang` using Windows-1252 or ANSI encoding instead of UTF-8. | Re-save the `.lang` file in your code editor explicitly using **UTF-8** encoding (without BOM). |
Reference, straight from the game files
Read out of the game itself, so the ids match the version you are building for.
