A lightweight Imba module for loading and handling JSON-based localization files in web applications. This utility fetches a localization file, selects the appropriate language based on the user's browser settings (or falls back to a default), and allows you to easily access localized strings throughout your application. Package includes helpful components for language selection and localization management.
- 🔍 Automatic language detection - Uses the user's browser language settings
- 💾 Persistence: Stores user choice in local storage across sessions
- 🔄 Smart fallback system - Falls back to a default language when needed
- 🧠 Intuitive access - Proxy-based access to translation strings
- 📡 Event handling - Support for
onready
,onchange
, andonerror
events - 🚀 Simple integration - Easy to use in any Imba-based web application
- 🧩
<language-selector>
- Plug and play tag component for switching languages
- Language detection uses the first two characters from
navigator.language
(e.g.,en
fromen-US
) - If the preferred language isn't available in your JSON file, it falls back to the default language
- Returns an empty string for missing translation keys instead of throwing errors
# NodeJs
npm install imba-localization
# or Bun
bun add imba-localization
Add this to your HTML head to load the localization file simultaneously with your application:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Other head elements -->
<link rel="preload" href="path/to/lang.json" as="fetch" type="application/json" crossorigin="anonymous"/>
</head>
<body>
<!-- Your app -->
</body>
</html>
💡 Tip: You can host your localization file on GitHub Pages or any static hosting service, making it easy to update translations without redeploying your application.
# app.imba
import { Localization } from 'imba-localization'
# Create an instance with the JSON URL and optional default language
const loc = new Localization("path/to/lang.json", "en")
# Set up event handlers
loc.onready = do
console.log "Localization loaded!"
# Access translations in various ways:
console.log loc.hello # Using dot notation
console.log loc['goodbye'] # Using bracket notation
console.log loc['user']['profile'] # Accessing nested properties
loc.onerror = do(error, details)
# The Localization object can return following types of errors:
# 'no_localization_file' - if there were a problem when downloading JSON file
# 'no_default_localization' - if there is no localization in the file for the default language
# 'no_localization_key' - if there is no requiered (from the interface) key in the file
console.error "Localization error:", error, details
loc.onchange = do(lang_key)
console.log "Language changed to:", lang_key
# Get the current localization code
console.log loc.active
# Switch the active language
loc.active = "fr" # Changes to French if available
# Loop through all the localizations
for key, data of loc.languages
console.log key, data
# Get all the keys for the active language
console.log loc.languages[loc.active]
Your localization file should follow this format:
{
"en": {
"welcome": "Welcome",
"goodbye": "Goodbye",
"user": {
"profile": "Profile",
"settings": "Settings"
}
},
"fr": {
"welcome": "Bienvenue",
"goodbye": "Au revoir",
"user": {
"profile": "Profil",
"settings": "Paramètres"
}
}
}
new Localization(url, default = 'en')
-
url
: Path to your JSON localization file -
default
: Fallback language code (defaults to 'en')
-
active
: Get or set the code of the active language -
languages
: Object containing all loaded language data -
preferred
: Detected browser language (first 2 characters ofnavigator.language
)
-
onready
: Called when localization data is successfully loaded -
onerror
: Called when an error occurs (error
,details
) -
onchange
: Called when the active language changes (lang_key
)
A customizable dropdown component that allows users to select from available in the JSON localization file languages.
import { Localization } from 'imba-localization'
const loc = new Localization("path/to/lang.json", "en")
# after importing Localization object
# <language-selector> tag will be available
# in any of you project your UI component
tag AppHeader
<self>
<language-selector state=loc> # state attribute is mandatory
To make this component work as intended, your JSON file will need some adjustments. For each supported language you will need to define the display name for the language and also the country code for the flag to show (for example en
language is used in gb
and us
countries):
"en": {
"$": {
"name": "English",
"flag": "us"
}
}
Here are CSS classes (and one variable) you can redefine:
css
$ease: 0.5s
.main
cursor:pointer
rd:8px px:15px py:8px
bgc:light-dark(#000000/10, #FFFFFF/20)
fw:500 fs:13px
ead:$ease
bd:1px solid transparent
.main-active
bgc:light-dark(#000000/20, #FFFFFF/30)
bd:1px solid transparent
.main-flag
mr:10px rd:50% w:20px h:20px
bd:1px solid transparent
.main-name
mr:10px
bd:1px solid transparent
.main-arrow
w:16px h:16px ml:auto
fill:light-dark(#000000,#FFFFFF)
bd:1px solid transparent
transition: transform $ease ease
scale-y:-1
.main-arrow-active
bd:1px solid transparent
scale-y:1
.menu
t:100% l:50% x:-50% mt:2px rd:8px rd:8px py:5px zi:999
fw:500 fs:13px
backdrop-filter:blur(20px)
bd:1px solid transparent
bgc:light-dark(#000000/5, #FFFFFF/10)
ead:$ease
.menu-item
cursor:pointer
bd:1px solid transparent
d:hflex px:10px py:5px rd:8px m:5px
bg@hover:light-dark(#000000/10, #FFFFFF/20)
.menu-item-icon
bd:1px solid transparent
h:20px w:20px mr:10px rd:50%
.menu-item-text
fs:13px
<language-selector>
can be easily customized through CSS and Imba tag (class) inheritance. Here how the above classes can be adjusted via the inheritance, or through CSS selectors:
import { Localization } from 'imba-localization'
const loc = new Localization("path/to/lang.json", "en")
# --------------------
# Inheritance
# --------------------
# Create an inheritent class
tag custom-languages < language-selector
css
$ease: 1s
.menu-item rd:2px
.menu-item-icon h:30px w:30px
# Using the adjusted component
tag MyApp
<self>
<custom-languages state=loc>
# --------------------
# CSS selectors
# --------------------
global css
language-selector
@not(#_) # is needed for higher precedence
.main
bgc: #992033
bc: #992033
.main-active
bgc: blue2
bc: #992033
.menu
bgc: #992033
bc: #992033
.menu-item
bgc@hover: orange4
c@hover: black
# Using component that will be restyled
tag MyApp
<self>
<language-selector state=loc>
You can redefine the collection of flag icons through the icons
attribute:
<language-selector icons='https://flagicons.lipis.dev/flags/4x3/##.svg'>
There are many flag collections out there:
- https://kapowaz.github.io/square-flags/flags/##.svg (default one)
- https://hatscripts.github.io/circle-flags/flags/##.svg
- https://flagcdn.com/##.svg
- https://cdn.simplelocalize.io/public/v1/flags/##.svg
- https://cdn.jsdelivr.net/gh/hampusborgos/country-flags@main/svg/##.svg
- https://flagicons.lipis.dev/flags/4x3/##.svg
You can use any other collection you prefer, just change the actual country code to ##
in the url, so the component could replace it with the actual code to obtain a flag for a needed country.
You can use any arrow icon you prefer (or remove it though CSS) by passing a tag of the image to the LanguageSelector arrow
attribute:
const arrow = <path d="...">
<language-selector arrow=arrow>
The default arrow icon used in the LocalizationSelector component is available as a separate icon (in case for some reason you don't want to use imba-phosphor-icons package by Sindre).
import {path-arrow-down} from 'imba-localization'
tag App
<self>
<svg viewBox="0 0 256 256">
css w:20px h:20px stroke:red
<{svg-arrow-down}>