> ## Documentation Index
> Fetch the complete documentation index at: https://docs.passentry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Translating Passes: Localisation

> Learn how to localise digital passes so labels and values automatically appear in the user’s device language on Apple Wallet and Google Wallet, and how to configure localisation with PassEntry.

<Warning>
  Localisation is available based on plan entitlements.
  If your account does not currently have access, please contact PassEntry to enable this feature.
</Warning>

## Why Localisation Matters

Localisation makes sure that the fields on your pass (including labels and values) appear in the **preferred language of your users’ devices**.

* Improves user experience
* Builds trust and professionalism
* Reduces confusion for international customers

***

## 📱 How Devices Decide Which Language to Show

Both **Apple Wallet** and **Google Wallet** automatically match the **device language** with the localisations you’ve defined:

1. The device checks its **system language settings**.
2. It looks for a **matching localisation** in your pass.
3. If a match exists → that language version of the pass is shown.

👉 This means you don’t need to guess your user’s preferred language – the wallet handles it for you.

***

## ❓ What if a device uses an unsupported language?

Apple Wallet and Google Wallet handle fallbacks differently.

| Platform          | How the language is chosen when there’s **no exact match**                                                                                          |
| :---------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Apple Wallet**  | Tries device preferred languages → if none match, searches for English localisation → if not present, defaults to first localisation alphabetically |
| **Google Wallet** | Tries device locale → if none match, falls back to the template `defaultLanguage`                                                                   |

Example showing the mismatch:

* Default language set on the template: Icelandic (`is`)
* Localisations present: `fr`, `de`, `en`
* Device language: `it` (Italian)

**Apple Wallet:** displays English |
**Google Wallet:** displays Icelandic

<Warning>
  To make behaviour consistent across Apple and Google and ensure a safe and predictable fallback we recommend to always **set the default language to English**.
</Warning>

***

## 🌐 Supported Locale Options

Both Apple and Google use **[BCP 47 language tags](https://en.wikipedia.org/wiki/IETF_language_tag)** to define locales.
These tags combine a language code (e.g. `en` for English, `fr` for French) with optional region or script codes (e.g. `en-GB` for British English, `pt-BR` for Brazilian Portuguese).
You can look up the language you need in the [Wikipedia list of IETF language tags](https://en.wikipedia.org/wiki/IETF_language_tag) and use the corresponding code when adding localisations to your pass.

PassEntry supports a wide range of locales used by Apple and Google. You can include multiple localisations per pass template.

Here’s the current list of supported locales:

```javascript theme={null}
SUPPORTED_LOCALES = [
  "af", "am", "ar", "arn", "ary", "as", "az", "ba", "be", "bg", "bn", "bo", "br", "bs", "ca", "ckb", "co", "cs", "cy", "da", "de", "dsb", "dv", "el", "en", "es", "et", "eu", "fa", "fi", "fil", "fo", "fr", "fy", "ga", "gd", "gil", "gl", "gsw", "gu", "ha", "he", "hi", "hr", "hsb", "hu", "hy", "id", "ig", "ii", "is", "it", "iu", "ja", "ka", "kk", "kl", "km", "kn", "ko", "kok", "ku", "ky", "lb", "lo", "lt", "lv", "mi", "mk", "ml", "mn", "moh", "mr", "ms", "mt", "my", "nb", "ne", "nl", "nn", "no", "oc", "or", "pap", "pa", "pl", "prs", "ps", "pt", "pt-BR", "pt-PT", "quc", "qu", "rm", "ro", "ru", "rw", "sa", "sah", "se", "si", "sk", "sl", "sma", "smj", "smn", "sms", "sq", "sr", "st", "sv", "sw", "syc", "ta", "te", "tg", "th", "tk", "tn", "tr", "tt", "tzm", "ug", "uk", "ur", "uz", "vi", "wo", "xh", "yo", "zh", "zh-Hans", "zh-Hant", "zu"
]
```

***

## 📝 Example: Localised Supermarket Membership Pass

Let’s walk through a simple case study. Imagine a supermarket in France that issues a digital loyalty card. They want the pass to appear in English by default for tourists, while also providing a French translation for their local customers.

Below is a minimal pass template definition with localisation applied:

```json theme={null}
{
  "passTemplate": {
    "name": "PassEntry Supermarket",
    "templateType": "generic",
    "defaultLanguage": "en",
    "centralTitle": "PassEntry Supermarket",
    "notificationHeader": "PassEntry Supermarket",
    "description": "PassEntry Supermarket",
    "colors": {
      "background": "#dbdbdb",
      "label": "#000000",
      "text": "#000000"
    },
    "images": {
      "banner": "https://example.com/images/banner.jpg",
      "logo": "https://example.com/images/logo.jpg",
      "icon": "https://example.com/images/icon.jpg"
    },
    "fields": {
      "header": {
        "one": {
          "id": "points",
          "label": "Points",
          "defaultValue": "0",
          "localisation": {
            "fr": {
              "label": "Points",
              "defaultValue": "0"
            }
          }
        }
      },
      "central": {
        "one": {
          "id": "membershipTier",
          "label": "Tier",
          "defaultValue": "Silver",
          "localisation": {
            "fr": {
              "label": "Niveau",
              "defaultValue": "Argent"
            }
          }
        }
      },
      "details": {
        "one": {
          "id": "discount",
          "label": "Discount",
          "defaultValue": "15%",
          "localisation": {
            "fr": {
              "label": "Réduction",
              "defaultValue": "15%"
            }
          }
        },
        "two": {
          "id": "memberId",
          "label": "Member ID",
          "localisation": {
            "fr": {
              "label": "Identifiant membre"
            }
          }
        }
      }
    },
    "barcode": {
      "enabled": true,
      "type": "qr",
      "source": "extId"
    }
  }
}
```

## 🗝️ Pass Value Localisation

In addition to localising **labels** and **default values** at the template level, you can also localise **field values** directly when creating or updating a pass.<br />
This is especially useful for dynamic, user-specific data (like membership tier, discount, or status), ensuring the right translation is shown without requiring multiple template versions.

Example use case:

* A loyalty programme upgrades certain users from **Level 1** to **Level 2**.
* By localising the pass value directly, you can update each user’s pass once and rely on localisation to handle all supported languages.

### Example: Localised Membership Tier Value

```json theme={null}
{
  "pass": {
    "membershipTier": {
      "value": "Level 2",
      "localisation": {
        "fr": { "value": "Niveau 2" },
        "es": { "value": "Nivel 2" },
        "de": { "value": "Stufe 2" }
      }
    }
  }
}
```

***

### Notes

* **`defaultLanguage`:** Always set to `en` for a consistent fallback on both Apple and Google Wallet.
* **Localisation scope:** Added for labels and static default values where appropriate. Avoid defaults for dynamic customer data (e.g. name, email, member ID).
* **How `defaultLanguage` works:**
  * If `defaultLanguage` is set to `en`, then the parent-level `"label": "Tier", "defaultValue": "Silver"` are already in English.
  * ❌ Do **not** repeat English under the `localisation` object – it’s redundant.
  * ✅ Only add translations for other languages (e.g. `fr`, `de`).
* **Changing the default language later:**
  If you decide to make French your default language, you must:
  1. Update the parent-level label and default value to French.
  2. Remove `fr` from the `localisation` object.
  3. (Optionally) add `en` as a localisation if you still want English support.
* **Always include all localisation entries when updating a pass template or pass:**<br />
  If you previously set up French, Spanish, and German and then send an update with only German, the French and Spanish translations will be **removed**.

### Example

**Default language = English**

```json theme={null}
{
  "label": "Tier",
  "defaultValue": "Silver",
  "localisation": {
    "fr": {
      "label": "Niveau",
      "defaultValue": "Argent"
    }
  }
}
```

**Default language switched to French**

```json theme={null}
{
  "label": "Niveau",
  "defaultValue": "Argent",
  "localisation": {
    "en": {
      "label": "Tier",
      "defaultValue": "Silver"
    }
  }
}
```

<Tip>To test localisation on your phone, install your pass, change the language preferences in your device settings and then return to the Wallet app.</Tip>


## Related topics

- [Changelog](/changelog/2025/updates.md)
- [Create Pass Template](/api-reference/v1/pass-templates/create-pass-template.md)
