feat(web): add multi-language support (en, fr, de, es, it)#142
feat(web): add multi-language support (en, fr, de, es, it)#142
Conversation
7be3f1b to
470cb25
Compare
0ab952a to
6063a26
Compare
c6a7c7a to
7d373bc
Compare
7d373bc to
80a9627
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds client-side internationalization to the web UI (5 languages) and modernizes static asset delivery (ES modules, minification, gzip, and tiered caching) while updating docs and tests accordingly.
Changes:
- Introduce i18n utilities + JSON locale packs and wire them into
index.html/getmsg.htmlwith a language selector. - Refactor frontend JS to ES6 modules and add UI tweaks (custom file input, language selector styling).
- Add gzip middleware + tiered cache headers for static assets, plus Docker build-time minification and related tests/docs.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| web/static/utils.js | Adds ES-module utilities including i18n detection/loading/application + meta tag updates |
| web/static/index.js | Initializes i18n on the send page and adds custom file input behavior |
| web/static/getmsg.js | Initializes i18n on the retrieve page and keeps CSP-safe event wiring |
| web/static/index.html | Adds language selector, data-i18n hooks, and switches scripts to type="module" |
| web/static/getmsg.html | Adds language selector, data-i18n hooks, and switches scripts to type="module" |
| web/static/locales/en.json | English translation keys |
| web/static/locales/fr.json | French translation keys |
| web/static/locales/de.json | German translation keys |
| web/static/locales/es.json | Spanish translation keys |
| web/static/locales/it.json | Italian translation keys |
| web/static/application.css | Styles language selector + custom file input |
| web/static/icons/manifest.json | Fixes icon paths to /static/icons/... |
| web/static/icons/browserconfig.xml | Fixes tile icon path to /static/icons/... |
| internal/server.go | Enables gzip, updates rate limiting, and replaces static routing with cache-tier handlers |
| internal/handlers.go | Adds HTML/static handlers with caching headers and basic language header handling |
| internal/server_test.go | Updates rate-limit test and adds gzip compression test coverage |
| deploy/Dockerfile | Adds a Node-based minification stage and copies minified static assets into the final image |
| README.md | Documents multi-language support and updates frontend asset details/screenshots |
You can also share your feedback on Copilot code review. Take the survey.
4149d9e to
8577b5c
Compare
…css) Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
There was a problem hiding this comment.
Pull request overview
Adds client-side internationalization to the web UI (5 languages) and adjusts server/static delivery to support the new asset layout and performance goals (tiered caching + gzip).
Changes:
- Refactors frontend JS into ES modules and introduces a
data-i18n-driven translation system with async-loaded locale JSON files. - Updates HTML/CSS to add a language selector and translate UI strings + meta tags.
- Updates Go server routing/middleware for gzip compression and tiered caching of static assets; updates Docker build to minify web assets.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
web/static/utils.js |
Adds ES module utilities + i18n loading/detection/switching logic. |
web/static/index.js |
Imports utils as a module, initializes i18n, updates custom file input behavior. |
web/static/index.html |
Adds language selector, data-i18n attributes, switches script loading to ES modules. |
web/static/getmsg.js |
Imports utils as a module, initializes i18n, minor handler refactors. |
web/static/getmsg.html |
Adds language selector, data-i18n attributes, switches script loading to ES modules. |
web/static/application.css |
Styles language selector and custom file input. |
web/static/locales/en.json |
English translation keys for i18n. |
web/static/locales/fr.json |
French translation keys for i18n. |
web/static/locales/de.json |
German translation keys for i18n. |
web/static/locales/es.json |
Spanish translation keys for i18n. |
web/static/locales/it.json |
Italian translation keys for i18n. |
web/static/icons/manifest.json |
Fixes icon paths to match /static/icons/.... |
web/static/icons/browserconfig.xml |
Fixes tile icon path to match /static/icons/.... |
internal/server.go |
Enables gzip middleware; replaces static serving with tiered-cache static routes. |
internal/handlers.go |
Adds Vary helpers, HTML/static asset handlers with caching, language header handling. |
internal/server_test.go |
Updates rate-limit test and adds gzip coverage. |
deploy/Dockerfile |
Adds a Node-based stage to minify HTML/CSS/JS/JSON static assets during image build. |
README.md |
Documents i18n feature and updates frontend dependency details/screenshots. |
5a476db to
f645ed6
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
deploy/Dockerfile:82
- The permissions step only applies
chmod 644to top-level entries under./static/*, so files in nested directories (e.g../static/icons/*,./static/locales/*,./static/fonts/*) keep whatever permissions they had in the build stage. Consider switching tofind ./static -type f -exec chmod 644 {} \;(and-type dfor 755) so all copied static assets end up with consistent non-executable permissions.
# Set proper file permissions
RUN chmod 755 ./sup3rS3cretMes5age \
&& chmod 644 ./static/* \
&& find ./static -type d -exec chmod 755 {} \;
Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
…JS arch Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… header Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
…ge async and using monotonic request IDs to discard stale translation loads Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
4b13789 to
a0c4afd
Compare
Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>
…changes Signed-off-by: Jeremy JACQUE <jeremy.jacque@algolia.com>

Summary
This PR introduces comprehensive internationalization (i18n) support to the application, enabling users to view the interface in 5 languages: English, French, German, Spanish, and Italian.
Note: This PR is built on top of PR #140 and PR #143 (already merged)
Static Asset Size Analysis
Core Files (minified)
(Minified)
(Minified & Gzipped)
(Minified & Gzipped)
New Translation Files
(Minified & Gzipped)
Total Impact
Note: Translation files are loaded asynchronously on-demand (only the selected language is fetched), so the actual page load increases by only ~435 bytes uncompressed or ~280 bytes gzipped + one locale file (~300 bytes gzipped).
Gzip Compression: The Gzip middleware provides ~70% compression on text assets, reducing total transfer size from 20.4KB to 6.1KB. This makes the multi-language feature essentially bandwidth-neutral compared to the original.
Changes Overview
Core Features
Technical Details
utils.js Module:
detectLanguage(): Auto-detect from URL param?lang=fror browserisValidLanguage(): Validate supported language codes (en, fr, de, es, it)loadTranslations(): Fetch JSON translations asynchronouslyapplyTranslations(): Update DOM elements withdata-i18nattributesupdateMetaTags(): Update title, description, Open Graph tagsswitchLanguage(): Change language with URL persistenceCSP Compliance:
onchange="..."withaddEventListener()UI Improvements:
langattribute updatesPerformance Optimization:
Vary: Accept-EncodingheadersTesting
?lang=frmaintains selectionRelated Commits
c03c956- Add minify step for static resourcesd3fe4fa- Add language header support in handlers2a9bebf- Add multi-lang support (en,fr,es,de,it)Performance Impact