README: - Added prominent live demo banner at the top with links to https://evershelfproject.dadaloop.it/demo and project website Wiki (docs/wiki/): - Home.md — overview, table of contents, what's new - Installation.md — Docker, Apache, Nginx, HTTPS, cron, backup - Configuration.md — full .env reference, settings UI, rate limits - Features.md — complete feature documentation - API-Reference.md — all REST endpoints with params/responses - Android-Kiosk.md — setup wizard, permissions, troubleshooting - Scale-Gateway.md — BLE protocol, setup, troubleshooting - Translations.md — how to add/edit language files - Contributing.md — dev workflow, branch strategy, CI, code style - FAQ.md — common issues and solutions
3.7 KiB
🌍 Translations
EverShelf uses JSON translation files in the translations/ folder. The app auto-detects the browser language on load and falls back to English.
Currently Supported Languages
| Language | File | Status |
|---|---|---|
| 🇮🇹 Italian | translations/it.json |
✅ Complete (base language) |
| 🇬🇧 English | translations/en.json |
✅ Complete |
| 🇩🇪 German | translations/de.json |
✅ Complete |
Adding a New Language
1. Copy the base file
cp translations/it.json translations/fr.json
2. Translate all values
Open fr.json in your editor and translate every value (leave the keys unchanged).
{
"app": {
"name": "EverShelf",
"loading": "Chargement..." ← translate this
},
"nav": {
"title": "🏠 EverShelf", ← keep emoji, translate text
"home": "Accueil"
}
}
Rules:
- Never change the key names (left side of
:) - Keep
{placeholder}tokens unchanged — they are replaced at runtime- Example:
"toast.added": "Added {name} to {location}"— keep{name}and{location}
- Example:
- Keep HTML tags if present (rare):
<strong>,<br> - Keep emojis (they are part of the UX design)
- Plurals: some keys have
_one/_manyvariants — translate both
3. Register the language in the app
Open assets/js/app.js and find the SUPPORTED_LANGUAGES constant (near the top):
const SUPPORTED_LANGUAGES = ['it', 'en', 'de'];
Add your language code:
const SUPPORTED_LANGUAGES = ['it', 'en', 'de', 'fr'];
4. Add the language to translations/ badge list
Update the README.md badge:
[](translations/)
5. Test
Open the app with ?lang=fr in the URL to force your language:
http://localhost:8080/?lang=fr
Check for missing keys — they will show the raw key name in the UI (e.g. nav.title).
6. Submit a PR
Open a pull request with your new translations/fr.json and the updated app.js line. See Contributing.
Translation Key Structure
The file is a nested JSON object. Here are the main sections:
| Section | Description |
|---|---|
app |
General app strings |
nav |
Navigation labels |
btn |
Button labels |
locations |
Storage location names |
categories |
Product category names |
dashboard |
Dashboard section titles |
inventory |
Inventory page strings |
use |
Use/consume form strings |
add |
Add product form strings |
scan |
Barcode scanner strings |
recipes |
Recipe page strings |
cooking |
Cooking mode strings |
shopping |
Shopping list strings |
log |
Transaction log strings |
settings |
Settings page strings |
scale |
Scale integration strings |
toast |
Toast notification messages |
error |
Error messages |
confirm |
Confirmation dialog strings |
Updating Existing Translations
If a new feature adds keys to it.json (the base), you need to add the same keys to en.json and de.json.
The CI pipeline validates that all language files contain the same keys — a missing key will fail the build.
To check locally:
node -e "
const it = require('./translations/it.json');
const en = require('./translations/en.json');
// flatten and compare keys...
"
Or just open a PR — CI will flag any missing keys automatically.
Language Detection Order
?lang=xxURL parameter (forces a specific language)localStorage.getItem('lang')(last manually selected language)navigator.language/navigator.languages(browser preference)- Fallback:
en
Users can change the language in Settings → Language.