-
Notifications
You must be signed in to change notification settings - Fork 834
feat: software localization (i18n support) #11723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@nshcr is attempting to deploy a commit to the GitButler Team on Vercel. A member of the Team first needs to authorize it. |
Byron
left a comment
There was a problem hiding this 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' |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 { | |||
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
dd9e4bb to
b5394ec
Compare
b5394ec to
51e0866
Compare
51e0866 to
8dac9b3
Compare
Screen.Recording.2026-01-11.at.21.42.34.movThis 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:
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: |
|
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 🫂. |
|
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. |
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.
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. |
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.