Conversation
…gement and translation loading
- Add i18n to DeleteModal.svelte (delete_connection, confirm_delete, cannot_undo) - Add connection_deleted and connection_delete_failed to +page.svelte - Add new translation keys to en.yaml and es.yaml
There was a problem hiding this comment.
Pull request overview
Adds a shared internationalization layer across the Go TUI/CLI and the Svelte web UI, including language persistence in settings and an API endpoint to serve translations to the web frontend.
Changes:
- Introduces a Go
internal/i18npackage with embedded YAML locales (en/es) and formatting helpers, plus config support for a persisted language. - Adds
/api/i18n(and related) web endpoints and updates Svelte pages/components to render all user-facing strings via i18n, including a language selector in Settings. - Refactors many TUI/CLI strings to use i18n keys and adds a web build step change.
Reviewed changes
Copilot reviewed 47 out of 47 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| web-svelte/src/routes/settings/+page.svelte | i18n-driven Settings UI + language selector |
| web-svelte/src/routes/+page.svelte | Localized toast messages on delete |
| web-svelte/src/routes/+layout.svelte | Initializes web i18n on mount |
| web-svelte/src/lib/stores/settings.svelte.ts | Adds language to settings state |
| web-svelte/src/lib/i18n/index.ts | New Svelte i18n store + translator |
| web-svelte/src/lib/components/TunnelCard.svelte | Localizes tunnel card UI strings |
| web-svelte/src/lib/components/Toasts.svelte | Localizes toast close aria-label |
| web-svelte/src/lib/components/ThemeSelector.svelte | Localizes “Current theme” label |
| web-svelte/src/lib/components/ThemeButton.svelte | Minor class update (cursor) |
| web-svelte/src/lib/components/SettingsToggle.svelte | Localizes enable/disable aria-label |
| web-svelte/src/lib/components/NotificationPermission.svelte | Localizes notification permission UI |
| web-svelte/src/lib/components/NewConnection.svelte | Localizes new connection form + toasts |
| web-svelte/src/lib/components/Header.svelte | Localizes app name/tagline + settings aria |
| web-svelte/src/lib/components/EditConnection.svelte | Localizes edit connection form + toasts |
| web-svelte/src/lib/components/Dropdown.svelte | Adds i18n defaults for dropdown labels |
| web-svelte/src/lib/components/DeleteModal.svelte | Localizes delete confirmation modal |
| web-svelte/src/lib/components/ConnectionsPanel.svelte | Localizes connections panel empty/loading |
| web-svelte/src/lib/api/index.ts | Exports Settings type |
| web-svelte/src/lib/api/endpoints/settings.ts | Adds language to Settings API type |
| scripts/build-web-assets.sh | Runs bun install before build |
| internal/web/handlers.go | Routes /api/i18n endpoints |
| internal/web/handlers_settings.go | Adds language setting + i18n JSON endpoints |
| internal/i18n/locales/es.yaml | New Spanish translations |
| internal/i18n/locales/en.yaml | New English translations |
| internal/i18n/i18n.go | New core i18n store + helpers |
| internal/i18n/helpers.go | Provider/status/notification helper translators |
| internal/i18n/embed.go | Embeds locale YAMLs + load helpers |
| internal/config/config.go | Persists language in config |
| internal/app/view.go | Localizes TUI loading/status messages |
| internal/app/update.go | Localizes download/status feedback |
| internal/app/ui/views/settings.go | Localizes settings view + language selector |
| internal/app/ui/views/logs.go | Localizes logs view header/hints |
| internal/app/ui/views/list.go | Localizes list view headers/messages |
| internal/app/ui/views/form.go | Localizes form labels/hints/buttons |
| internal/app/ui/views/empty.go | Localizes empty state copy |
| internal/app/ui/views/downloading.go | Localizes downloading/install UI |
| internal/app/ui/components/tunnel_item.go | Localizes tunnel list item status/badges |
| internal/app/ui/components/help_bar.go | Localizes help bar shortcuts |
| internal/app/ui/components/detail_panel.go | Localizes detail panel labels/actions |
| internal/app/model.go | Localizes install failure error message |
| internal/app/model_types.go | Localizes list item description text |
| internal/app/keyhandlers_settings.go | Adds language cycling + persistence |
| internal/app/keyhandlers_list.go | Localizes list actions + errors |
| internal/app/form.go | Localizes validation + success messages |
| internal/app/app.go | Loads translations + initializes language |
| desktop/main.go | Removes embed directive for desktop assets |
| cmd/ftm/main.go | Localizes CLI output strings |
Comments suppressed due to low confidence (2)
web-svelte/src/lib/components/Dropdown.svelte:38
ariaLabel/labeldefaults are computed once fromt("options")during props destructuring, so they won’t update when the language changes. Prefer deriving a computed label reactively (e.g.const computed = $derived(label ?? t('options'))) and use that in the template, or default toundefinedand translate at render time.
cmd/ftm/main.go:56i18n.T/TFare used beforeapp.New()is called (e.g.--versionand--uninstallpaths), but translations are only loaded insideapp.New()right now. This means these code paths will print raw keys (and formatted strings will be wrong). Initialize i18n (load translations and set language) before any early-return flag handling that uses it.
func main() {
var (
webOnly = flag.Bool("web", false, "Start web dashboard and open browser")
server = flag.Bool("server", false, "Start web dashboard only (no browser)")
port = flag.Int("port", 0, "Web server port (auto-detect if not specified)")
showVersion = flag.Bool("version", false, "Show version")
uninstall = flag.Bool("uninstall", false, "Uninstall ftm")
)
flag.Parse()
if *showVersion {
fmt.Println(i18n.TF("version_output", version.Version))
os.Exit(0)
}
if *uninstall {
doUninstall()
os.Exit(0)
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes