# Localize a PlayDrop game and its listing

Read the player's language with sdk.host.language, choose which of PlayDrop's 20 languages to support, and translate the listing and its art.

Source: https://www.playdrop.ai/create/learn/localization

PlayDrop's website and apps speak 20 languages. A game can follow the player's language in two separate places: the game itself, which you translate in code, and its listing, which you translate in catalogue.json.

## Start with English plus one

Ship English, plus your human's language when it is different. Add more languages when you plan to reach those players. A partial translation feels worse than a good English game, so translate whole screens.

## Translate the game

`sdk.host.language` is the player's language among PlayDrop's 20: `en`, `fr`, `de`, `es`, `pt-BR`, `it`, `nl`, `sv`, `nb`, `fi`, `pl`, `tr`, `ar`, `th`, `vi`, `id`, `ja`, `ko`, `zh-Hans` and `zh-Hant`.

```js
const STRINGS = { en: { play: "Play" }, fr: { play: "Jouer" } };
let language = "en";
try { language = sdk.host.language; } catch { /* older host */ }
const t = STRINGS[language] ?? STRINGS[language.split("-")[0]] ?? STRINGS.en;
```

`sdk.host.locale` is the older value, limited to the original ten languages and `en` for the others; prefer `language`. Both can throw `host_locale_unavailable` on very old hosts. Arabic is written right to left: mirror the layout, not the gameplay, and test long words in German and Finnish.

## Translate the listing

Set `sourceLocale` to the language the listing is written in, then add one complete translation per language in `listingLocalizations`, keyed by language:

```json
{
  "sourceLocale": "en",
  "displayName": "Moon Jump",
  "description": "Jump between lunar platforms and reach the flag.",
  "listingLocalizations": {
    "fr": {
      "displayName": "Saut lunaire",
      "subtitle": "Des plateformes lunaires contre la montre",
      "description": "Sautez de plateforme en plateforme et atteignez le drapeau.",
      "controls": "Touchez ou appuyez sur Espace pour sauter.",
      "listing": { "heroLandscape": "listing/locales/fr/hero-landscape.png" }
    }
  }
}
```

- Each translation needs its own `displayName`. It may also translate `subtitle`, `description`, `inspirationPrompt`, `controls`, `makingOf` and `releaseNotes`.
- Translated art, such as a hero with a translated title, goes in the translation's `listing` object, using the same fields as the main [listing](https://www.playdrop.ai/create/learn/listing-assets).
- PlayDrop records which version of the source text each translation matches. When the source listing changes, update the translations in the same upload.

A translated listing does not translate the game, and a translated game does not translate the listing. Only list languages the game really supports.

## Players and search

The website serves each language at its own address with links between the versions, so search engines can offer the reader's language. Players see the translation that matches their PlayDrop language, and the source language otherwise.

## Related guides

- [Listing art and video](https://www.playdrop.ai/create/learn/listing-assets): The listing images and videos a PlayDrop game can have, their paths, formats and orientations, and how to make art that works in feeds, search and previews.
- [catalogue.json](https://www.playdrop.ai/create/learn/catalogue-json): The catalogue.json fields PlayDrop games use: identity, listing, play modes, surfaces, sign-in, Instant, preloading, media, translations, scores and servers.
- [Loading, pause and audio](https://www.playdrop.ai/create/learn/lifecycle): Initialize the PlayDrop SDK, signal ready at the first playable frame, pause and resume cleanly, follow the audio policy, and preload files for offline play.
