Complete reference for slang-roblox.yaml configuration file.
base_locale: en
supported_locales:
- en
- es
- id
input_directory: translations
output_directory: output
# Localization mode (NEW in v2.x)
localization:
mode: embeddedThe base locale used as fallback when translations are missing.
Type: string
Example: en, en-US, id, es-MX
base_locale: enSupported Locales:
en- Englishes- Spanishid- Indonesianpt- Portuguesede- Germanfr- Frenchja- Japaneseko- Koreanzh-CN- Chinese (Simplified)zh-TW- Chinese (Traditional)- And 14 more Roblox-supported locales
List of locales to generate translations for.
Type: array of strings
Example:
supported_locales:
- en
- es
- id
- pt
- deNote: The base_locale should be included in this list.
Directory containing translation files (JSON/YAML).
Type: string
Default: translations
input_directory: translationsStructure:
translations/
├── en.json
├── es.json
└── id.jsonDirectory where generated Luau code will be written.
Type: string
Default: output
output_directory: outputGenerated files:
output/
├── Translations.lua # Main module
├── types/
│ └── Translations.d.luau # Type definitions
└── roblox_upload.csv # CSV for Roblox CloudCustom namespace for generated code. If not specified, uses Translations.
Type: string | null
Default: null (uses Translations)
namespace: MyTranslationsUsage:
local MyTranslations = require(ReplicatedStorage.MyTranslations)
local t = MyTranslations.new("en")NEW in v2.x: Configure how translations are loaded at runtime.
Type: object
Default: { mode: "embedded" }
localization:
mode: embeddedType: string
Options: embedded, cloud, hybrid
Default: embedded
Controls how translations are loaded at runtime:
embedded (Default)
Translations are embedded directly in the generated Luau code. No cloud dependency.
localization:
mode: embeddedPros:
- Works offline (no LocalizationService dependency)
- Fastest performance (direct table lookup)
- No cloud setup required
- Perfect for single-player or offline games
Cons:
- No Automatic Text Capture (ATC)
- No automatic translation via Roblox AI
- Manual translation management
Generated code:
-- Translations embedded in EMBEDDED_TRANSLATIONS table
local t = Translations.new("en")
print(t.ui.buttons:buy()) -- Direct lookup from embedded datacloud
Uses Roblox Cloud LocalizationService exclusively. Requires uploading translations to Roblox Cloud.
localization:
mode: cloudPros:
- Automatic Text Capture (ATC) integration
- Automatic translation via Roblox AI
- Translator Portal collaboration
- Analytics via Roblox Dashboard
Cons:
- Requires cloud setup and upload
- Depends on LocalizationService availability
- Requires internet connection
Generated code:
-- Uses LocalizationService:GetTranslatorForLocaleAsync()
local t = Translations.new("en")
print(t.ui.buttons:buy()) -- Fetches from LocalizationServiceRequirements:
- Must run
roblox-slang uploadto sync translations to cloud - Requires cloud configuration in
slang-roblox.yaml
hybrid
Best of both worlds: tries cloud first, falls back to embedded on error.
localization:
mode: hybridPros:
- Cloud features when available (ATC, auto-translation)
- Embedded fallback for reliability
- Graceful degradation on cloud errors
- Works in Studio and production
Cons:
- Slightly larger generated file size (includes embedded data)
- More complex setup
Generated code:
-- Tries LocalizationService with pcall, falls back to embedded
local t = Translations.new("en")
print(t.ui.buttons:buy()) -- Tries cloud, falls back to embeddedUse Cases:
- Games transitioning from embedded to cloud
- Games that need offline support with cloud benefits
- Development (Studio) vs production (cloud) workflows
Comparison:
| Feature | Embedded | Cloud | Hybrid |
|---|---|---|---|
| Offline support | ✅ Yes | ❌ No | ✅ Yes |
| Cloud features (ATC, auto-translate) | ❌ No | ✅ Yes | ✅ Yes |
| Performance | ⚡ Fastest | 🐢 Slower | 🚀 Fast |
| Setup complexity | 🟢 Simple | 🔴 Complex | 🟡 Medium |
| File size | 📦 Larger | 📄 Smaller | 📦 Larger |
| Reliability | ✅ High | ✅ High |
Override specific translations for A/B testing or seasonal events.
overrides:
enabled: true
file: overrides.yamloverrides.enabled
Type: boolean
Default: false
Enable/disable override system.
overrides.file
Type: string
Default: overrides.yaml
Path to overrides file (relative to project root).
Example overrides.yaml:
en:
ui.buttons.buy: "Purchase Now!" # Override for A/B test
es:
ui.buttons.buy: "¡Comprar Ahora!"Priority: overrides.yaml > translations/*.json
Track missing translations and usage statistics.
analytics:
enabled: true
track_missing: true
track_usage: trueanalytics.enabled
Type: boolean
Default: false
Enable analytics tracking in generated code.
analytics.track_missing
Type: boolean
Default: false
Track when translations are missing (logs to console).
analytics.track_usage
Type: boolean
Default: false
Track how often each translation is accessed.
Usage:
local t = Translations.new("en")
-- Get usage statistics
local stats = t:getUsageStats()
print(stats["ui.buttons.buy"]) -- Number of times accessed
-- Get missing translations
local missing = t:getMissingKeys()
for _, key in ipairs(missing) do
print("Missing:", key)
end# Base locale (fallback)
base_locale: en
# Supported locales
supported_locales:
- en
- es
- id
- pt
- de
- fr
- ja
- ko
# Input/output directories
input_directory: translations
output_directory: src/shared/Translations
# Custom namespace (optional)
namespace: null
# Localization mode (NEW in v2.x)
localization:
mode: embedded # or "cloud" or "hybrid"
# Translation overrides (for A/B testing, seasonal events)
overrides:
enabled: true
file: overrides.yaml
# Analytics tracking
analytics:
enabled: true
track_missing: true
track_usage: trueYou can use environment variables in configuration:
base_locale: ${BASE_LOCALE:-en}
output_directory: ${OUTPUT_DIR:-output}Syntax: ${VAR_NAME:-default_value}
Example:
export BASE_LOCALE=es
export OUTPUT_DIR=dist/translations
roblox-slang buildValidate your configuration:
roblox-slang validateThis checks:
- Required fields are present
- Locale codes are valid
- Directories exist
- Translation files are valid JSON/YAML
- No duplicate keys
- All locales have same keys
Always ensure your base locale has all translation keys. Other locales can be incomplete (will fallback to base).
Use dot notation for nested keys:
{
"ui.buttons.buy": "Buy",
"ui.buttons.sell": "Sell"
}Or nested structure:
{
"ui": {
"buttons": {
"buy": "Buy",
"sell": "Sell"
}
}
}Both work, but nested is more readable.
Group translations by feature/screen:
{
"shop": { ... },
"inventory": { ... },
"settings": { ... }
}Only use overrides for temporary changes (A/B tests, events). Keep main translations in translation files.
Enable analytics during development to find unused translations:
analytics:
enabled: true
track_usage: trueThen review usage stats before release.
If you have an old configuration format, migrate using:
roblox-slang migrate configThis will convert old format to new format automatically.
- Getting Started - Initial setup guide
- Pluralization - Handle plural forms
- String Interpolation - Parameter usage
- Roblox Cloud Integration - Upload to Roblox Cloud
- Rojo Integration - Use with Rojo