# Localization Example

**URL:** <https://forum.defold.com/t/localization-example/82108>\
**Category:** The Defoldmine\
**Created:** [December 16, 2025, 5:28am UTC](https://forum.defold.com/t/localization-example/82108 "2025-12-16T05:28:42Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![d954mas](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/d954mas/32/5401_2.png) [@d954mas](https://forum.defold.com/u/d954mas)\
**Post date:** [December 16, 2025, 5:28am UTC](https://forum.defold.com/t/localization-example/82108/1 "2025-12-16T05:28:43Z")

</div>

# Defold Localization example

> **[GitHub - d954mas/defold-localization](https://github.com/d954mas/defold-localization/tree/main)**
>
> main

This is example how to use google sheet table for localization.

Localization support plurals and placeholders.

Example use 2 fonts. One for all languages and one for set of languages without chinese, japanese and korean. You can run game with small font and use liveupdate to download full font.

 ![locale_ch](https://forum-defold-uploads.b-cdn.net/original/3X/3/1/31e60c94995782d9a2de145e955ea724e4c45b12.png)

 ![locale_en](https://forum-defold-uploads.b-cdn.net/original/3X/1/0/1089eedb2ed7b8b45d39db140d36eb03d9010d8b.png)

## How to use

1. You will need credentials.json to download from google sheets.

2. Copy localization folder in your project

- Add files to .gitignore

```lua
/localization/load_localization/node_modules
/localization/load_localization/package-lock.json
/localization/load_localization/token.json
/localization/load_localization/credentials.json
/localization/load_localization/localization/\*\*

```

- Install node dependencies.

```lua
cd localization/load_localization
npm install

```

1. Config index.js

Paste your spreadsheet id to config\_sheet variable.

Use you sheet name and range

```js

async function main(auth) {

console.log(“start”);

const sheets = google.sheets({version: ‘v4’, auth});

// https://docs.google.com/spreadsheets/d/1BUmB7w0f4RVaqfJtRp3ix_3HKL0V5Izu-I9MB9NhCX4

const config_sheet = “1BUmB7w0f4RVaqfJtRp3ix_3HKL0V5Izu-I9MB9NhCX4”

let localization = await download_localization(sheets, “localization!A8:L1000”, auth, config_sheet);

```

1. Download localization

```lua

cd ./localization/load_localization

node index.js

```

You will have 6 files.

- Font forge scripts to exclude symbols from ttf file.

font\_forge\_all.txt

font\_forge\_small.txt

- Localization data in json format. You will need localization\_compact.json for your game.

localization.json

localization\_compact.json

- Symbols list in txt format. To include symbols in defold .font files

symbol\_list.txt

symbol\_list\_small.txt

1. Google sheets localization

[Example spreadsheet](https://docs.google.com/spreadsheets/d/1BUmB7w0f4RVaqfJtRp3ix_3HKL0V5Izu-I9MB9NhCX4/edit#gid=0)

 ![google_sheets](https://forum-defold-uploads.b-cdn.net/original/3X/c/4/c416a494c6c0666debf5dbab9d94d7a0b1dbe875.png)

1. Add localization\_compact.json to custom resources

2. Use localization in your game. Look in localization.lua and main.gui\_script for example.

```lua
--localization.lua

local I18N = require “localization.i18n.init”

local TAG = “[LOCALIZATION]”

-–@class Localization

local M = {

}

function M:init(locale)
    self.config_all = localization.load_localization_from_resources(“custom/localization_compact.json”)
    self.config_tiny @class {}
    for k, v in pairs(M.config_all) do
        if k ~= “ko” and k ~= “zh” and k ~= “ja” then
            self.config_tiny[k] = v
        end
    end

    I18N.load(self.config_tiny)
    I18N.setFallbackLocale(“en”)
    self:set_locale(assert(locale))
end

function M:set_locale(locale)
    print(TAG, “set locale:” .. locale)
    I18N.setLocale(locale)
    –you can create events or use messages to trigger components when language is changed
    –EVENTS.LANGUAGE_CHANGED:trigger()
end

function M:locale_get()
    return I18N.getLocale()
end

function M:translate(key, data)
    local translation = I18N.translate(key, data)
    if not translation then
        print(TAG, “translation not found:” .. key)
        return key
    end
    return translation
end

function M:is_exist(id)
    return I18N.translate(id) ~= nil
end

function M:on_font_loaded(font_all)
    self.font_all = assert(font_all)
    I18N.load(self.config_all)
    –add delay to fix some font not changed it metrics
    –timer.delay(0.1, false, function ()
    – EVENTS.LANGUAGE_CHANGED:trigger()
    –end)
end

return M

--main.gui_script

local function on_language_changed(self)
    local language_str = LOCALIZATION:translate(“language”)
    local date_str = os.date(“%d.%m.%Y”)
    local test_locale = LOCALIZATION:translate(“test_locale”, {language = language_str, date = date_str})

    gui.set_text(gui.get_node(“title”), test_locale)
    gui.set_text(gui.get_node(“load_font_status”), LOCALIZATION.font_all and “font loaded” or “font not loaded”)
    gui.set_text(gui.get_node(“msg_zero”), LOCALIZATION:translate(“messages”, {count = 0}))
    gui.set_text(gui.get_node(“msg_one”), LOCALIZATION:translate(“messages”, {count = 1}))
    gui.set_text(gui.get_node(“msg_two”), LOCALIZATION:translate(“messages”, {count = 2}))
    gui.set_text(gui.get_node(“msg_few”), LOCALIZATION:translate(“messages”, {count = 5}))
    gui.set_text(gui.get_node(“msg_many”), LOCALIZATION:translate(“messages”, {count = 10}))
    gui.set_text(gui.get_node(“msg_other”), LOCALIZATION:translate(“messages”, {count = 20}))

end

```

---

<div class="post-metadata">

**Author:** ![Alexander\_Bulatov](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/alexander_bulatov/32/27139_2.png) [@Alexander\_Bulatov](https://forum.defold.com/u/Alexander_Bulatov)\
**Post date:** [December 17, 2025, 5:48pm UTC](https://forum.defold.com/t/localization-example/82108/2 "2025-12-17T17:48:02Z")

</div>

Thanks! It’s very useful for me!
