Localization
Add translations and customize text for your language.
This guide explains how to add translations and customize text in Oxide Banking.
Table of Contents
- Overview
- Locale File Structure
- Adding a New Language
- Translation Categories
- Using Variables in Translations
Overview
Oxide Banking uses QBCore's locale system for text translations. All translatable text is stored in locale files located in the locales/ folder.
Default Language: English (locales/en.lua)
Locale File Structure
Each locale file follows this structure:
local Translations = {
error = {
-- Error messages
},
success = {
-- Success messages
},
info = {
-- Informational messages
},
-- Additional categories...
}
if GetConvar('qb_locale', 'en') == 'XX' then -- XX = language code
Lang = Locale:new({
phrases = Translations,
warnOnMissing = true,
})
end
Adding a New Language
Step 1: Create New Locale File
- Copy
locales/en.luato create your new locale file - Name it with the appropriate language code (e.g.,
es.luafor Spanish,de.luafor German)
locales/
├── en.lua # English (default)
└── es.lua # Spanish (new)
Step 2: Translate the Content
Open your new locale file and translate all text values:
-- locales/es.lua
local Translations = {
error = {
bank_error = 'No se puede acceder a los servicios bancarios',
no_card = 'Necesitas una tarjeta bancaria para usar el cajero',
not_enough_money = 'Fondos insuficientes',
-- ... translate all entries
},
success = {
withdraw = 'Retirado exitosamente $%{amount}',
deposit = 'Depositado exitosamente $%{amount}',
-- ... translate all entries
},
-- Continue for all categories...
}
if GetConvar('qb_locale', 'en') == 'es' then
Lang = Locale:new({
phrases = Translations,
warnOnMissing = true,
})
end
Step 3: Update fxmanifest.lua
Add your new locale file to the shared_scripts in fxmanifest.lua:
shared_scripts {
'@qb-core/shared/locale.lua',
'locales/en.lua',
'locales/es.lua', -- Add your new locale
-- ... other files
}
Step 4: Set Server Language
Set the language in your server.cfg:
set qb_locale "es"
Translation Categories
Error Messages (error)
Messages shown when something goes wrong:
error = {
bank_error = 'Unable to access banking services',
no_card = 'You need a bank card to use the ATM',
not_near_atm = 'You are not near an ATM',
cancelled = 'Action cancelled',
not_enough_money = 'Insufficient funds',
not_enough_cash = 'Not enough cash',
withdraw_failed = 'Withdrawal failed',
deposit_failed = 'Deposit failed',
transfer_failed = 'Transfer failed',
player_not_found = 'Player not found',
account_exists = 'An account with that name already exists',
daily_limit_exceeded = 'Daily limit exceeded',
account_frozen = 'This account has been frozen',
invalid_input = 'Invalid input',
invalid_pin = 'Invalid PIN',
loan_denied = 'Loan application denied',
-- Card-related errors
card_not_found = 'Card not found',
card_not_active = 'Card is not active',
not_card_owner = 'You do not own this card',
invalid_old_pin = 'Current PIN is incorrect',
invalid_new_pin = 'New PIN must be 4 digits',
}
Success Messages (success)
Messages shown on successful operations:
success = {
withdraw = 'Successfully withdrew $%{amount}',
deposit = 'Successfully deposited $%{amount}',
transfer = 'Transfer completed successfully',
account_opened = 'Account created successfully',
card_ordered = 'Bank card ordered successfully',
user_added = 'User added to account',
loan_approved = 'Loan approved',
loan_payment = 'Loan payment successful',
card_frozen = 'Card frozen successfully',
card_unfrozen = 'Card unfrozen successfully',
card_pin_changed = 'Card PIN changed successfully',
}
Info Messages (info)
Informational text and prompts:
info = {
press_to_open = '[E] Open Bank',
press_to_use_atm = '[E] Use ATM',
processing = 'Processing...',
loading = 'Loading...',
}
Progress Messages (progress)
Text shown during progress bars:
progress = {
accessing_atm = 'Accessing ATM...',
processing_transaction = 'Processing transaction...',
}
Target Labels (target)
Labels for qb-target interactions:
target = {
open_bank = 'Open Bank',
use_atm = 'Use ATM',
}
Notifications (notify)
Notification messages with dynamic content:
notify = {
deposit_title = 'Deposit Received',
deposit_message = '$%{amount} deposited to %{account}',
withdraw_title = 'Withdrawal',
withdraw_message = '$%{amount} withdrawn from %{account}',
transfer_received_title = 'Transfer Received',
transfer_received_message = 'Received $%{amount} from %{from}',
loan_due_title = 'Loan Payment Due',
loan_due_message = 'Payment of $%{amount} due in %{days} days',
interest_title = 'Interest Earned',
interest_message = 'You earned $%{amount} in interest',
}
Account Types (account_types)
Labels for account types:
account_types = {
checking = 'Checking Account',
savings = 'Savings Account',
shared = 'Shared Account',
job = 'Business Account',
gang = 'Organization Account',
}
Account Tiers (tiers)
Labels for account tiers:
tiers = {
basic = 'Basic',
premium = 'Premium',
business = 'Business',
}
Loan Types (loan_types)
Labels for loan products:
loan_types = {
personal = 'Personal Loan',
vehicle = 'Vehicle Loan',
property = 'Property Loan',
business = 'Business Loan',
emergency = 'Emergency Loan',
}
Credit Ratings (credit_ratings)
Labels for credit score ratings:
credit_ratings = {
excellent = 'Excellent',
very_good = 'Very Good',
good = 'Good',
fair = 'Fair',
poor = 'Poor',
very_poor = 'Very Poor',
}
UI Labels (ui)
General UI text:
ui = {
bank_name = 'Fleeca Digital Banking',
welcome = 'Welcome',
accounts = 'Accounts',
transactions = 'Transaction History',
transfer = 'Transfer Money',
loans = 'Loans',
investments = 'Investments',
settings = 'Settings',
logout = 'Exit',
deposit = 'Deposit',
withdraw = 'Withdraw',
balance = 'Balance',
amount = 'Amount',
submit = 'Submit',
cancel = 'Cancel',
confirm = 'Confirm',
credit_score = 'Credit Score',
enter_pin = 'Enter PIN',
}
Using Variables in Translations
Some translations include dynamic variables using the %{variable} syntax:
-- Definition
success = {
withdraw = 'Successfully withdrew $%{amount}',
}
-- Usage in code (handled automatically)
Lang:t('success.withdraw', { amount = 500 })
-- Result: "Successfully withdrew $500"
Common Variables
| Variable | Description | Example |
|---|---|---|
%{amount} | Money amount | 5000 |
%{account} | Account name | 'checking' |
%{from} | Sender name | 'John Doe' |
%{to} | Recipient name | 'Jane Doe' |
%{days} | Number of days | 7 |
%{type} | Type/category | 'Personal Loan' |
%{remaining} | Remaining balance | 10000 |
%{goal} | Goal name | 'New Car' |
%{product} | Product name | 'Savings Bond' |
%{returns} | Return amount | 1500 |
%{reason} | Reason text | 'Suspicious activity' |
%{balance} | Account balance | 2500 |
%{card_number} | Masked card number | '**** 1234' |
Language Codes Reference
Common language codes:
| Code | Language |
|---|---|
en | English |
es | Spanish |
fr | French |
de | German |
pt | Portuguese |
it | Italian |
nl | Dutch |
pl | Polish |
ru | Russian |
zh | Chinese |
ja | Japanese |
ko | Korean |
Tips for Translators
- Keep placeholders intact - Don't translate
%{amount}or similar variables - Match text length - Try to keep translations similar in length to originals
- Test in-game - Verify translations display correctly in the UI
- Use proper encoding - Save files in UTF-8 encoding
- Check for missing keys -
warnOnMissing = truewill log missing translations
Complete Locale Template
For reference, here's the complete structure of en.lua:
local Translations = {
error = { ... },
success = { ... },
info = { ... },
progress = { ... },
target = { ... },
notify = { ... },
account_types = { ... },
tiers = { ... },
loan_types = { ... },
credit_ratings = { ... },
ui = { ... },
}
if GetConvar('qb_locale', 'en') == 'en' then
Lang = Locale:new({
phrases = Translations,
warnOnMissing = true,
})
end
Oxide Banking by Oxide Studios