Skip to content

Conversation

@nshcr
Copy link
Contributor

@nshcr nshcr commented Jan 7, 2026

Screen.Recording.2026-01-07.at.11.44.21.mov

This draft PR originated from a small experiment of mine, attempting to port the core functionality of vue-i18n (https://github.com/intlify/vue-i18n) to other frontend frameworks. It's the i18n library I'm most familiar with and one I consider reliable.

Thanks to vue-i18n's well-designed layering of core functionality, this turned out to be surprisingly easy. Its core package is distributed independently and is framework-agnostic, so I implemented a simple Svelte compatibility layer to make it work seamlessly with Svelte's reactivity system.

I put together this PR fairly quickly to experiment with using the ported library in a real project, and the results matched my expectations perfectly.

Given the amount of work required for proper localization, this PR may remain in draft status for a long time. I'm sharing it mainly to signal to others who care about this feature that the idea is feasible and that it's an active work in progress.

There are many i18n libraries available in the Svelte ecosystem. My choice to port vue-i18n is largely personal: it's feature-rich, actively maintained, and developed directly by the Vue core team, which gives me confidence in its long-term maintenance and support.

That said, a downside is that it's not an i18n solution designed specifically for Svelte, so its level of framework-specific integration is relatively low. However, it fits well with GitButler's service-injection-based architecture, reduces coupling to a specific frontend framework, and allows localization to be introduced incrementally.

Below are some other Svelte i18n libraries I've looked into. Their functionality is broadly similar and they're listed here for comparison.

@vercel
Copy link

vercel bot commented Jan 7, 2026

@nshcr is attempting to deploy a commit to the GitButler Team on Vercel.

A member of the Team first needs to authorize it.

@nshcr
Copy link
Contributor Author

nshcr commented Jan 7, 2026

@Byron Byron added the C-Tracking Issue Category: A meta-issue that keeps track of a more general matter label Jan 7, 2026
Copy link
Collaborator

@Byron Byron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for posting this PR!

I see it like a spike to see how this could look like, and as a platform to learn more and communicate. With that said, it's a background task and everything is very async.
To me, posting here also comes with quite a bit of multi-faceted excitement, so excuse all these questions 😅.

export default {
settings: {
language: 'Sprache',
selectLanguage: 'Wählen Sie Ihre bevorzugte Sprache'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be interesting - in German there is the formal "Sie" and just "Du".
Without making this a suggestion, I feel we'd probably want to be the 'cool' people use "du" all the time.
That's good to figure out in general: formal or informal?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The German translations were generated by Claude - actually, the Chinese and Japanese ones were as well :P.

For the Chinese translations, It used the more formal form "您", as opposed to the more casual "你". I think this is comparable to the distinction between "Sie" and "Du" in German - different forms of the word "you". Similarly, the Japanese translations use polite expressions too (such as "〜てください", roughly equivalent to "please").

As for whether to choose a more formal tone or a more casual / informal one, I personally think either is fine. Once a decision is made, it can serve as a baseline for future translations.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I asked @schacon just now and he brought up an interesting consideration: since it's the Butler talking, would they not talk formally? That would be kind of funny as well :D.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case he were Jimmy Butler... just kidding.

I don't think this is a particularly important issue - being more formal won't go wrong, and being more casual is unlikely to bother anyone either.

If I had to choose, I'd lean toward using a more casual tone in the Chinese translations, as it helps reduce the sense of distance between the product and its users.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And that is another option: Some languages might be more susceptible to such a 'joke' - I'd find it funny to see it use the formal version, like a butler probably would.

Maybe it's personal, maybe it's general, and if it's general, other languages might have different preferences for this, i.e. for some it's just formal and not at all funny.

What would be funny (and clearly kind of unnecessary, but still) is to have a checkbox for the formality of the language :D. I have never seen this, and this is what makes it cool.

Beautiful bike-shed 😅.

@@ -0,0 +1,24 @@
export default {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would there have to be a type for this data so we get compiler errors if something new is added, forcing us to fill in translations?

Or is this an anti-feature given that the one adding a new thing is unlikely to be able to translate all languages instantly.

Something I am after is a way to at some point ensure nothing stays untranslated, and if there is no way around it, at least to see the status of each translation.

In any case, I am curious to hear your thoughts and learn from your experience.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enabling type-safe localization is a great strategy, and it's already part of my plan. typesafe-i18n (https://github.com/codingcommons/typesafe-i18n) is an excellent library for implementing this approach, and vue-i18n can also achieve it by defining a schema (https://vue-i18n.intlify.dev/guide/advanced/typescript.html). That said, this PR is currently just a quick draft, and I haven't organized the type declarations yet, I'll refine this part later.

And there's also a fallback language mechanism in place: any untranslated strings will fall back to English, which is more friendly for both development workflows and nightly releases.

Type-safe checks for localized strings could act as a gatekeeper for stable releases rather than a hard requirement during development. I think I can implement this via a separate linting script.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot, all that makes sense to me and it looks like a solved problem.

@nshcr nshcr force-pushed the feat-i18n-support branch from dd9e4bb to b5394ec Compare January 9, 2026 17:01
@nshcr nshcr force-pushed the feat-i18n-support branch from b5394ec to 51e0866 Compare January 11, 2026 13:35
@nshcr nshcr force-pushed the feat-i18n-support branch from 51e0866 to 8dac9b3 Compare January 11, 2026 13:40
@nshcr
Copy link
Contributor Author

nshcr commented Jan 11, 2026

Screen.Recording.2026-01-11.at.21.42.34.mov

This PR is currently pushed as two commits. The first commit adds the underlying code support for software localization, and the second commit completes localization for most global settings and some project settings in Chinese, Japanese, and German, with a focus on providing parity across four languages: English, Chinese, Japanese, and German.

The English localization strings are extracted directly from the existing codebase. The German, Chinese, and Japanese translations were initially batch-generated by Claude Sonnet 4.5. The Chinese translations were then carefully reviewed and refined by me line by line. For Japanese, I only did a quick pass and did not notice any major issues. The German translations were cross-checked by Claude based on the other three languages. Japanese and German still require review by native speakers to ensure the accuracy of the AI-generated translations.

@Byron, if you have time, I'd really appreciate it if you could help take a look at the German translations. I also want to sincerely thank you for continuously supporting the localization effort - this PR would not have reached its current state without your encouragement.

Optimistically speaking, I think this PR probably completes around 60-80% of the frontend UI text localization. I believe most of the visible text lives in the settings pages. @PavelLaptev, you may have a clearer picture of the overall UI text volume, so I'd appreciate any advice or guidance you might have here.

Unfortunately, due to some sudden personal reasons, I'm no longer able to invest additional time into the localization work for this project. Given that GitButler may not be planning to release a multilingual version in the near future, the timeline for merging this PR into main is uncertain.

The longer this PR remains in draft status, the more likely it is that the large number of modified components will run into merge conflicts as the project evolves. I personally don't have the energy to keep resolving those conflicts. Localization requires first-class support from the core team, it's very difficult to sustain the initial momentum purely through community efforts. Once things are properly set in motion, the situation can naturally improve over time with community support.

That said, I'm not trying to rush anyone here. My hope is simply that the work I've done can provide a small push forward, moving GitButler one step closer to serving non-English-speaking users. As the product becomes more widely known, more users will inevitably want it translated into their native languages (from what I've seen, requests for Chinese localization are especially common). If official support never materializes, the community may eventually choose to fork and go their own way.

In addition to translation work, this PR also leaves several items unfinished. Below is a list of things I personally had planned but didn't get to complete:

  • Automatically detecting the user's system language and switching accordingly
  • Translating the application menu bar (not critical, but nice to have)
  • Uploading the user's locale as telemetry data (which I imagine could be valuable to you)
  • More complete type-safe support and missing-translation checks (I won't have time to push this further, the current level of type safety is usable)
  • Localization of but command output (not strictly necessary, given the rapid iteration of but, this is probably lowest priority)
  • Frontend styling improvements for localized messages (localized strings can't embed custom components like <Link>, which means link styling in some texts needs adjustment)

As for the core i18n service implementation, as mentioned in the opening post, I used the core library of vue-i18n. I also surveyed and listed most of the available i18n solutions for Svelte that I could find. If you feel another framework would be a better fit, please feel free to replace it. The core functionality is easy to swap out - the bulk of the work lies in text extraction, which rarely needs to change with framework choices.

Finally, here is the simplified AI prompt I used as a reference for generating and reviewing the translations:

Review the localization translations for Chinese, Japanese, English, and German file by file and field by field. English is the source text. Chinese is a human-reviewed reference translation. Japanese and German are AI-generated translations.

The translations should be professional and accurate. The tone should match the English as closely as possible, if the original tone is unclear, prefer a casual and relaxed style.

Carefully consider the differences between languages and perform this task step by step and patiently. Do not guess when unsure - look up the relevant code context where the string is used.

If you find any missing translations in any language, fill them in following the same standards.

@Byron
Copy link
Collaborator

Byron commented Jan 12, 2026

Thank you so much for pushing this topic so relentlessly, it's also close to my heart and I will keep it alive in your absence, hoping that in the end, everything will be alright for you again.

Having pondered about what to do, I decided it's best to see this PR as a spike to show what's possible, and to explore the space. #11783 was created to track everything we know, and most of the text is copied from you (not always properly attributed though).

Knowing that i18n isn't currently a priority, and that I'd love it if the whole team could give it a big push to come to fruition when it's time, I think it's best to treat this PR as a spike and close it, knowing that the knowledge gained will not be lost.

I'd also want to CC @mtsgrd if there is a desire to merge this PR with the language selector behind a feature toggle, but I keep thinking that we'd have trouble maintaining what's there even, with the added indirection for strings in the settings slowing down development, with the translations of other languages rotting away.

Thus, it's best to close this issue and get back to it once we can make a push. Lastly, I hope that an official tracking ticket will help those looking for it find what's on the horizon.

Thanks again for all your work, help and input, you will be missed 🫂.

@Byron Byron closed this Jan 12, 2026
@nshcr
Copy link
Contributor Author

nshcr commented Jan 12, 2026

Oh, I'm still here! I just don't have much time to dedicate to GitButler at the moment. I think this will gradually improve over time, but right now I really need to focus all my energy on getting some life issues under control...

I still have about four or five PRs in progress that I haven't made public yet. One or two of them are minor bug fixes, a few are performance optimizations, and the rest add some really nice new features. If these issues haven't been addressed by GitButler in the future, I may come back to finish them.

I also really appreciate you making the final decision on how to handle this PR. I've been going back and forth on whether I should close it myself, because I didn't want my request to disrupt the team's original plans.

And if the team decide to move forward with localization in the future, I'd still be very happy to help review the Chinese translations - that's something I'm confident I can make time for.

@Byron
Copy link
Collaborator

Byron commented Jan 12, 2026

Oh, I'm still here! I just don't have much time to dedicate to GitButler at the moment. I think this will gradually improve over time, but right now I really need to focus all my energy on getting some life issues under control...

Apologies, and thanks for clarifying this. That's much better, of course, and I am glad that by closing this PR this will help to focus on the other fixes you have coming up. And regarding those features, I am definitely curious and look forward to when they land.

And if the team decide to move forward with localization in the future, I'd still be very happy to help review the Chinese translations - that's something I'm confident I can make time for.

You will be the first one on my mind then! And I'd also hope that GitHub Sponsors is setup (by then at the latest) so we can properly support the Chinese translation, and who knows what else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-Tracking Issue Category: A meta-issue that keeps track of a more general matter @gitbutler/desktop

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants