TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Lessons From Linguistics: i18n Best Practices for Front-End Developers

188 点作者 open-source-ux将近 2 年前

25 条评论

Etheryte将近 2 年前
In general a good short rule of thumb is to always always _always_ write out the full sentence you want to translate and use the tooling to interpolate everything you want to put in it. That way the translator always sees the full context and you make it harder (although not impossible) for yourself to shoot yourself in the foot. Another recommendation I would add is to use two meta locales in development in addition to whatever you need to support otherwise: id and pseudo. The id locale should be an identity function so you (and the translator and everyone else) can open up a page and see what keys are used on that page. The pseudo locale should be either random or pseudorandom text and is good for both ensuring you haven't accidentally left something hardcoded as well as checking how your layout plays with different length strings. These ideas alone will get you most of the way most of the time, and they have the added benefit that they're straightforward to teach to juniors.
评论 #37088074 未加载
评论 #37094356 未加载
评论 #37088259 未加载
评论 #37090017 未加载
dale_glass将近 2 年前
A particularly tricky case of this is with usernames and user defined content.<p>Eg, a notification like &quot;Alice is online&quot; in some languages requires knowing Alice&#x27;s gender. Which may be something that&#x27;s not even stored anywhere in the system. There&#x27;s probably some language out there that requires some other piece of personal info for a correct translation.<p>To make things tricky, try having a multitude of items that you refer to: &quot;You&#x27;re holding a dagger&quot;. Now you need to have a serious discussion with your translators, because this is going to get all kinds of tricky, as the maker of Obra Dinn discovered: <a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=OMi6xgdSbMA">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=OMi6xgdSbMA</a><p>And to make things extra-tricky, allow users to create content. &quot;Alice gave you a banana&quot;, where &quot;banana&quot; is a custom object Alice made herself.<p>Most translation efforts seem to give up at this point and resort to something stilted like &quot;Alice: online&quot;
评论 #37092948 未加载
评论 #37090144 未加载
评论 #37090180 未加载
评论 #37089946 未加载
评论 #37093512 未加载
yafbum将近 2 年前
Smells:<p>* If you&#x27;re concatenating sentence bits, you&#x27;re doing it wrong<p>* If you&#x27;re formatting numbers, dates, times, or durations by hand, you&#x27;re doing it wrong<p>* If you&#x27;re formatting strings with placeholders and you don&#x27;t know the gender and number of your placeholders, your translators are going to have a bad time<p>There are two more important rules that this article doesn&#x27;t mention<p>* Write long descriptions of what the thing is that you&#x27;re asking someone to translate (button label, menu item, dialog header...), and include a screenshot. Translating very short strings without context is very difficult.<p>* Ask your translators to do a global once-over QA pass once in a while to detect inconsistencies and weirdness. Once I dealt with a product that had three tabs, and two of the tabs were translated identically. Each tab header translation made sense on its own, but as distinct tab headers side by side, it made no sense to use the same word.
评论 #37091767 未加载
评论 #37092107 未加载
Wildgoose将近 2 年前
Another aspect to be aware of is that English is often much shorter than the equivalent translated text, especially on buttons with text labels. I remember many years ago we used a rough rule of thumb of always doubling the space used for English to ensure there was enough space for the translated text.
评论 #37087935 未加载
评论 #37087942 未加载
评论 #37091558 未加载
评论 #37092534 未加载
评论 #37087619 未加载
评论 #37093747 未加载
sergioisidoro将近 2 年前
It&#x27;s frustrating that the post does not provide any solution for some of the problems like declinations and gender. I internationalised a couple of applications, and it&#x27;s incredible how i18n frameworks are still so limited in linguistic aspects that are so important for so many languages.<p>Finnish, for example works with a ton of suffixes, and you end up having to rewrite the copy (to non natural structures) to fit interpolation and declinations. Portuguese genders almost every subject in a phrase construction.<p>The web is killing (or creating artificial versions) of many languages because the lack of tooling...
评论 #37089333 未加载
评论 #37087895 未加载
dheerajvs将近 2 年前
With formatjs [0], you don&#x27;t have to split the sentence for interpolation. The same example as in the article can be implemented as:<p><pre><code> const message = defineMessage({ defaultMessage: &#x27;Learn more about &lt;a&gt;supported images&lt;&#x2F;a&gt;.&#x27;, description: &#x27;Footer text containing a hyperlink&#x27;, }) </code></pre> and the anchor element can be interpolated as:<p><pre><code> formatMessage(message, { a: (chunks: ReactNode) =&gt; &lt;a href=&quot;#link&quot;&gt;{chunks}&lt;&#x2F;a&gt;, }) </code></pre> [0]: <a href="https:&#x2F;&#x2F;formatjs.io" rel="nofollow noreferrer">https:&#x2F;&#x2F;formatjs.io</a>
评论 #37087966 未加载
jakub_g将近 2 年前
Good article. Knowing some Slavic, Latin or Asian language helps immensely when dealing with i18n.<p>I wrote an article on a similar subject (with some additional technical details about Android and iOS) a few years ago, with a few similar conclusions:<p><a href="https:&#x2F;&#x2F;jakub.gieryluk.net&#x2F;blog&#x2F;reusing-software-translations-ios-android-web&#x2F;" rel="nofollow noreferrer">https:&#x2F;&#x2F;jakub.gieryluk.net&#x2F;blog&#x2F;reusing-software-translation...</a>
scriptsmith将近 2 年前
Don&#x27;t forget Right-To-Left languages, that also affects how UI elements are arranged (position within the page) and rendered (input widgets like sliders get reversed).
评论 #37087530 未加载
barbariangrunge将近 2 年前
I’m highly procedural game dev lots of text has unpredictable text inserted within it. Eg, a notification for how “(person 1) has left (room1) to perform (action) in (room2) with (item1)”<p>So your “never do interpolation” trick is a bit of an over-simplification already. Not to mention all the ways to modify a verb or noun with surrounding words, Eg, preceding it with the. I walked to Larry vs I walked to the couch<p>Our languages systems for our game got pretty complex, pretty fast, and I find these simplified hand wavy articles pretty frustrating tbh
h1fra将近 2 年前
Translation&#x2F;Internationalisation is one of the hardest problem that is not going to be solved by technology only.<p>RTL, plural depending on the number, non-latin char behavior, font issues, UI broken by longer translation, context dependent translation, etc. Every time I start a project or think about it I&#x27;m sweating.
评论 #37089148 未加载
评论 #37088546 未加载
zengid将近 2 年前
Can I just rant for a second about how much I hate the whole `&lt;starting-letter-of-a-word-&gt;&lt;count-of-inner-letters&gt;&lt;ending-letter-of-a-word&gt;` trend that folks seem to love? This intentional sort of obfuscation makes it hard for juniors or students (the exact people who would be interested in an article like this), to engage in the material. The most egregious example is doing it for the word &#x27;accessibility&#x27;!
评论 #37094285 未加载
Tainnor将近 2 年前
I think the Polish example is even a bit more complex than that: it&#x27;s not really that Polish has a separate form for &quot;a few&quot;. That&#x27;s the regular plural form. It&#x27;s that Polish uses the <i>genitive plural</i> with certain numerals, instead of the nominative. That is, instead of saying &quot;5 dogs&quot; you say &quot;5 of dogs&quot;.<p>This doesn&#x27;t, to my knowledge, apply if there is no numeral provided, even if we&#x27;re talking about 1000 dogs, so it wouldn&#x27;t be right to call it a plural.<p>Of course, the point of the article still stands.<p>Disclaimer: I don&#x27;t speak Polish. I did learn some Czech though at some point (most of which I&#x27;ve forgotten).
needle0将近 2 年前
Not covered here: fonts and glyph appearances, which will nearly always end up displaying wrong in certain Asian languages -- <a href="https:&#x2F;&#x2F;heistak.github.io&#x2F;your-code-displays-japanese-wrong&#x2F;" rel="nofollow noreferrer">https:&#x2F;&#x2F;heistak.github.io&#x2F;your-code-displays-japanese-wrong&#x2F;</a>
评论 #37105199 未加载
Kiala将近 2 年前
&gt; The order of the words is hardcoded, with “added” preceding the date. This would be incorrect in many languages, from Dutch (“1 januari toegevoegd”)<p>This is simply not true. Since English and Dutch are both Germanic languages they largely work the same way. Saying &quot;Toegevoegd: 1 januari&quot; would be just fine. By using &quot;1 januari toevoegd&quot; you&#x27;re syntactically changing the sentence.
评论 #37089422 未加载
AndrewOMartin将近 2 年前
It&#x27;s best practice to shorten &quot;Internationalization (i18n)&quot; to &quot;I25)&quot;
lucideer将近 2 年前
This is a good article, though as someone who prefers references&#x2F;tables to prose for technical topics, the real find for me was the link out to the Unicode CLDR project (which sadly contains a LOT of broken links right now due to a data migration effort but I&#x27;ll bookmark it &amp; hopefully it&#x27;ll be navigable in future).<p>As someone with a Polish partner, who also fluently speaks my own weird minority local language (Irish), I&#x27;m more than well aware of pluralisation pitfalls; Irish may have one of the most complex rulesets, so much so that I&#x27;m almost certain it isn&#x27;t represented in CDLR (possibly can&#x27;t be). But I see the plural pitfall brought up in so many of these guide - I&#x27;ve always been curious about other unexpected&#x2F;unintuitive pitfalls across languages out there. Would love if there was a simple reference of the most interesting (starting with plurals I guess).
评论 #37087849 未加载
评论 #37087375 未加载
FlorianZysset将近 2 年前
Unrelated but I had a weird experience navigating to this article on my IPhone: the music in my headset switched to call mode. I can reproduce that about 50% of the time.<p>Is there something using the microphone somewhere? Feels really weird…<p>14 Pro Max with latest beta software
MilStdJunkie将近 2 年前
I would give my little toe to see what this person&#x27;s opinion is on CCS&#x2F;CCMS (Component Content Systems)<p><a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Component_content_management_system" rel="nofollow noreferrer">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Component_content_management_s...</a><p>There&#x27;s quite a bit more to be written here about natural language, formal language, and how constituents of each class interact with each other. Stuff that the initial architects of &quot;component content&quot; were not necessarily thinking about, because they were coming at the problem from an extremely limited corpus.
bitigchi将近 2 年前
Also, number and percent formats are important too. I&#x27;ve seen many &#x27;professional&#x27; websites&#x2F;software, that uses only a standart 100.0% format, where the decimal and the percent are not localised.
higgins将近 2 年前
tangent:<p>did you know that &quot;institutionalization&quot; also resolves to the English numerical contraction: &quot;i18n&quot;?<p>here&#x27;s a tool to test for conflicts in other words (a11y, k8s, ets):<p><a href="https:&#x2F;&#x2F;encapsulate.me&#x2F;writing&#x2F;e25n.html" rel="nofollow noreferrer">https:&#x2F;&#x2F;encapsulate.me&#x2F;writing&#x2F;e25n.html</a>
评论 #37089996 未加载
samuelstros将近 2 年前
i am on a 2 year long rabbit hole to solve many i18n problems that devs face <a href="https:&#x2F;&#x2F;github.com&#x2F;inlang&#x2F;inlang">https:&#x2F;&#x2F;github.com&#x2F;inlang&#x2F;inlang</a><p>we are in our third (major) refactor because the problem is so complex and new requirements emerge regularly :&#x2F;
dolmen将近 2 年前
The post is interesting as it exposes the problem statement.<p>Unfortunately, I expected from a Shopify Engineering blog that it would provide <i>solutions</i> to this problem like a JS library for i18n.<p>Disclaimer: As I&#x27;m not a frontend developer I&#x27;m not familiar with the ecosystem solutions.
评论 #37087228 未加载
JanSt将近 2 年前
Is there some kind of Auto-i18n where the function sends a request to a server if there is no localization available? The server could in turn request a translation from a service and add it to the localization files
评论 #37087440 未加载
评论 #37087504 未加载
ChrisMarshallNY将近 2 年前
I&#x27;ve found that I need to support localization from the very start.<p>I never display a quoted string. I always use Apple&#x27;s tokenization (or create my own, if doing server code).<p>Apple has terrific support for localization, which puts the onus on us, to honor it. I have some basic extensions that I use to support localization in my coding[0-2], but there&#x27;s also just stuff I need to keep in mind, all the time.<p>There has been discussion of how to deal with things like word order in different languages. For example, in Germanic languages, the modifier usually precedes the subject, while in Romance languages, it tends to be the opposite.<p>Thankfully, Apple supports the &quot;$&quot; format for sprintf strings[3], so we can do stuff like this:<p><pre><code> import Foundation let localizationAssets = [ (format: &quot;The %1$@ %2$@&quot;, modifier: &quot;white&quot;, subject: &quot;horse&quot;), (format: &quot;Le %2$@ %1$@&quot;, modifier: &quot;blanc&quot;, subject: &quot;cheval&quot;) ] func localizedHorse(_ inLocalization: Int) -&gt; String { String( format: localizationAssets[inLocalization].format, localizationAssets[inLocalization].modifier, localizationAssets[inLocalization].subject ) } &#x2F;&#x2F; English (Prints &quot;The white horse&quot;) print(localizedHorse(0)) &#x2F;&#x2F; French (Prints &quot;Le cheval blanc&quot;) print(localizedHorse(1)) </code></pre> [0] <a href="https:&#x2F;&#x2F;github.com&#x2F;RiftValleySoftware&#x2F;RVS_Generic_Swift_Toolbox&#x2F;blob&#x2F;master&#x2F;Sources&#x2F;RVS_Generic_Swift_Toolbox&#x2F;RVS_Generic_Swift_Toolbox_Extensions&#x2F;RVS_Foundation_Extensions.swift#L184">https:&#x2F;&#x2F;github.com&#x2F;RiftValleySoftware&#x2F;RVS_Generic_Swift_Tool...</a><p>[1] <a href="https:&#x2F;&#x2F;github.com&#x2F;RiftValleySoftware&#x2F;RVS_Generic_Swift_Toolbox&#x2F;blob&#x2F;master&#x2F;Sources&#x2F;RVS_Generic_Swift_Toolbox&#x2F;RVS_Generic_Swift_Toolbox_Extensions&#x2F;RVS_Foundation_Extensions.swift#L192">https:&#x2F;&#x2F;github.com&#x2F;RiftValleySoftware&#x2F;RVS_Generic_Swift_Tool...</a><p>[2] <a href="https:&#x2F;&#x2F;github.com&#x2F;RiftValleySoftware&#x2F;RVS_Generic_Swift_Toolbox&#x2F;blob&#x2F;master&#x2F;Sources&#x2F;RVS_Generic_Swift_Toolbox&#x2F;RVS_Generic_Swift_Toolbox_Extensions&#x2F;RVS_Foundation_Extensions.swift#L200">https:&#x2F;&#x2F;github.com&#x2F;RiftValleySoftware&#x2F;RVS_Generic_Swift_Tool...</a><p>[3] <a href="https:&#x2F;&#x2F;developer.apple.com&#x2F;library&#x2F;archive&#x2F;documentation&#x2F;Cocoa&#x2F;Conceptual&#x2F;Strings&#x2F;Articles&#x2F;formatSpecifiers.html#&#x2F;&#x2F;apple_ref&#x2F;doc&#x2F;uid&#x2F;TP40004265-SW2" rel="nofollow noreferrer">https:&#x2F;&#x2F;developer.apple.com&#x2F;library&#x2F;archive&#x2F;documentation&#x2F;Co...</a>
评论 #37087553 未加载
评论 #37090414 未加载
lakomen将近 2 年前
<p><pre><code> I name them by component.context.phrase There&#x27;s https:&#x2F;&#x2F;cldr.unicode.org&#x2F;index . In Angular I liked Transloco [0] very much. For Vue I use vue-i18n, I don&#x27;t think there&#x27;s any alternative. For Go I like go-i18n [1] when doing SSR Go. For Svelte.. not sure if there&#x27;s a best package. [0] https:&#x2F;&#x2F;github.com&#x2F;ngneat&#x2F;transloco [1] https:&#x2F;&#x2F;github.com&#x2F;nicksnyder&#x2F;go-i18n</code></pre>