Wiki 9Minecraft Wiki 9Minecraft

Introduction to Text and Localization

How to display readable names, translate strings, and format text in Bedrock add-ons.

6Sections
4Code examples
3Known errors

Localization is the system Minecraft Bedrock uses to turn raw internal identifiers into readable text on the player's screen. Whenever you create a custom item, block, entity, or pack manifest, the game looks for a matching translation key inside your pack's `texts/` folder to display in the inventory or chat. Setting up your language files early keeps raw strings like `tile.custom:ruby_ore.name` out of your UI and lets you support multiple languages without touching your behavior or resource JSON files.

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.

RP/texts/languages.json
[
  "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.

RP/texts/en_US.lang
## 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 TypeDefault Key PatternNotes
Custom Blocktile.<namespace>:<id>.nameUsed 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>.nameOlder format versions append `.name` automatically.
Entityentity.<namespace>:<id>.nameShown in death messages, name tags, and `/say` output.
Spawn Eggitem.spawn_egg.entity.<namespace>:<id>.nameControls 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.

BP/items/amethyst_pickaxe.json
{
  "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.

RP/manifest.json
{
  "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.

CodeWhat it doesNotes
§0 - §9, §a - §fStandard 16 text colors`§a` is green, `§c` is red, `§e` is yellow, `§f` is white.
§lBold textApply after the color code, as applying a color resets bold.
§oItalic textItem names renamed on an anvil use this by default.
§kObfuscated (garbled) textContinuously cycles random characters of the same width.
§rReset formattingRestores 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 seeWhyThe 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.