[{"data":1,"prerenderedAt":1286},["ShallowReactive",2],{"\u002Fposts\u002Fvue-i18n-difficulties":3},{"id":4,"title":5,"body":6,"date":1276,"description":1277,"duration":1278,"extension":1279,"keywords":1280,"lang":508,"meta":1281,"navigation":220,"path":1282,"seo":1283,"stem":1284,"__hash__":1285},"posts\u002Fposts\u002F1.vue-i18n-difficulties.md","Difficulties you might encounter when using vue-i18n in real-world Vue.js applications",{"type":7,"value":8,"toc":1272},"minimark",[9,32,38,43,49,54,61,65,68,72,75,79,85,89,117,121,124,133,139,257,263,299,302,350,356,363,429,463,466,470,473,480,485,721,724,730,737,786,823,826,830,836,932,935,1123,1129,1132,1171,1268],[10,11,12,13,17,18,25,26,31],"p",{},"After few months of frustration with trying to use the \"de-facto\" internationalization library for Vue.js - ",[14,15,16],"code",{},"vue-i18n",", I've decided it's time to replace it. And that's why I have created ",[19,20,24],"a",{"href":21,"rel":22},"https:\u002F\u002Ffluent-vue.demivan.me",[23],"nofollow","fluent-vue",". I will write more about it and ",[19,27,30],{"href":28,"rel":29},"https:\u002F\u002Fprojectfluent.org\u002F",[23],"Fluent syntax"," it uses in my following blog posts.",[10,33,34,35,37],{},"In this blog post, I try to explain what problems I have encountered when trying to use the ",[14,36,16],{}," library in my app, and how fluent-vue and Fluent syntax solve them.",[39,40,42],"h3",{"id":41},"vue-i18n-good-parts","vue-i18n good parts:",[10,44,45,46,48],{},"Firstly, this is what I liked in ",[14,47,16],{},":",[50,51,53],"h4",{"id":52},"_1-component-interpolation","1. Component interpolation",[10,55,56,57,60],{},"Component interpolation allows using components inside translation messages. Nice way of reducing ",[14,58,59],{},"v-html"," directive usages.",[50,62,64],{"id":63},"_2-sfc-custom-blocks","2. SFC custom blocks",[10,66,67],{},"Keeping translations for the component in the same file as template and js code is really convenient.",[50,69,71],{"id":70},"_3-tooling","3. Tooling",[10,73,74],{},"Being the most used Vue.js internationalization library, it has a heap of useful packages and extensions.",[39,76,78],{"id":77},"vue-i18ns-issues","vue-i18n's issues:",[10,80,81,82,84],{},"And this is what I didn't like in ",[14,83,16],{}," or what didn't work for my project:",[50,86,88],{"id":87},"_1-complicated-api-for-developers","1. Complicated API for developers",[10,90,91,93,94,97,98,97,101,97,104,97,107,110,111,114,116],{},[14,92,16],{}," has 5 different methods: (",[14,95,96],{},"$t",", ",[14,99,100],{},"$tc",[14,102,103],{},"$te",[14,105,106],{},"$d",[14,108,109],{},"$n","). It has separate methods for formatting simple text, pluralized text, date, and numbers.",[112,113],"br",{},[14,115,24],{}," has only 2 methods and one of them is rarely used.",[50,118,120],{"id":119},"_2-leaky-localizations","2. \"Leaky\" localizations",[10,122,123],{},"Grammar of source language limits what features translators can use and leaks into app code and translations messages of other languages.",[10,125,126],{},[127,128,129],"em",{},[130,131,132],"strong",{},"Example (pluralization):",[10,134,135,136,138],{},"If you want translators to be able to use pluralization, you need to use ",[14,137,100],{}," method. Even if you don't need it for your source language. You can't just write:",[140,141,146],"pre",{"className":142,"code":143,"language":144,"meta":145,"style":145},"language-js shiki shiki-themes material-theme-lighter material-theme-lighter material-theme-palenight","const messages = {\n  en: {\n    'copy-n-files': 'Copy {count} files'\n  }\n}\n\n$t('copy-n-files', { count: filesCount })\n","js","",[14,147,148,168,179,203,209,215,222],{"__ignoreMap":145},[149,150,153,157,161,165],"span",{"class":151,"line":152},"line",1,[149,154,156],{"class":155},"smZ93","const",[149,158,160],{"class":159},"sZSNi"," messages ",[149,162,164],{"class":163},"sDfIl","=",[149,166,167],{"class":163}," {\n",[149,169,171,175,177],{"class":151,"line":170},2,[149,172,174],{"class":173},"sRlkE","  en",[149,176,48],{"class":163},[149,178,167],{"class":163},[149,180,182,185,188,191,193,196,200],{"class":151,"line":181},3,[149,183,184],{"class":163},"    '",[149,186,187],{"class":173},"copy-n-files",[149,189,190],{"class":163},"'",[149,192,48],{"class":163},[149,194,195],{"class":163}," '",[149,197,199],{"class":198},"sGFVr","Copy {count} files",[149,201,202],{"class":163},"'\n",[149,204,206],{"class":151,"line":205},4,[149,207,208],{"class":163},"  }\n",[149,210,212],{"class":151,"line":211},5,[149,213,214],{"class":163},"}\n",[149,216,218],{"class":151,"line":217},6,[149,219,221],{"emptyLinePlaceholder":220},true,"\n",[149,223,225,228,231,233,235,237,240,243,246,248,251,254],{"class":151,"line":224},7,[149,226,96],{"class":227},"s3cPz",[149,229,230],{"class":159},"(",[149,232,190],{"class":163},[149,234,187],{"class":198},[149,236,190],{"class":163},[149,238,239],{"class":163},",",[149,241,242],{"class":163}," {",[149,244,245],{"class":173}," count",[149,247,48],{"class":163},[149,249,250],{"class":159}," filesCount ",[149,252,253],{"class":163},"}",[149,255,256],{"class":159},")\n",[10,258,259,260,262],{},"You need to use ",[14,261,100],{}," method with additional parameter:",[140,264,266],{"className":142,"code":265,"language":144,"meta":145,"style":145},"$tc('copy-n-files', filesCount, { count: filesCount })\n",[14,267,268],{"__ignoreMap":145},[149,269,270,272,274,276,278,280,282,285,287,289,291,293,295,297],{"class":151,"line":152},[149,271,100],{"class":227},[149,273,230],{"class":159},[149,275,190],{"class":163},[149,277,187],{"class":198},[149,279,190],{"class":163},[149,281,239],{"class":163},[149,283,284],{"class":159}," filesCount",[149,286,239],{"class":163},[149,288,242],{"class":163},[149,290,245],{"class":173},[149,292,48],{"class":163},[149,294,250],{"class":159},[149,296,253],{"class":163},[149,298,256],{"class":159},[10,300,301],{},"And translators still have no way of knowing, without checking application code, whether translation that uses the following format would be pluralized.",[140,303,305],{"className":142,"code":304,"language":144,"meta":145,"style":145},"const messages = {\n  en: {\n    'copy-n-files': 'Copy {count} file | Copy {count} files'\n  }\n}\n",[14,306,307,317,325,342,346],{"__ignoreMap":145},[149,308,309,311,313,315],{"class":151,"line":152},[149,310,156],{"class":155},[149,312,160],{"class":159},[149,314,164],{"class":163},[149,316,167],{"class":163},[149,318,319,321,323],{"class":151,"line":170},[149,320,174],{"class":173},[149,322,48],{"class":163},[149,324,167],{"class":163},[149,326,327,329,331,333,335,337,340],{"class":151,"line":181},[149,328,184],{"class":163},[149,330,187],{"class":173},[149,332,190],{"class":163},[149,334,48],{"class":163},[149,336,195],{"class":163},[149,338,339],{"class":198},"Copy {count} file | Copy {count} files",[149,341,202],{"class":163},[149,343,344],{"class":151,"line":205},[149,345,208],{"class":163},[149,347,348],{"class":151,"line":211},[149,349,214],{"class":163},[10,351,352,353,355],{},"On top of that, if translator tries to use this syntax and developer didn't use ",[14,354,100],{}," method, it won't be pluralized and you will see both choice variants displayed in your app.",[10,357,358],{},[127,359,360],{},[130,361,362],{},"fluent-vue solution:",[140,364,368],{"className":365,"code":366,"language":367,"meta":145,"style":145},"language-ftl shiki shiki-themes material-theme-lighter material-theme-lighter material-theme-palenight","copy-n-files = { $count -> \n    [one] Copy file\n   *[other] Copy {$count} files\n}\n","ftl",[14,369,370,388,402,425],{"__ignoreMap":145},[149,371,372,376,379,382,385],{"class":151,"line":152},[149,373,375],{"class":374},"s52Pk","copy-n-files = ",[149,377,378],{"class":163},"{",[149,380,381],{"class":159}," $count ",[149,383,384],{"class":227},"->",[149,386,387],{"class":198}," \n",[149,389,390,393,396,399],{"class":151,"line":170},[149,391,392],{"class":227},"    [",[149,394,395],{"class":159},"one",[149,397,398],{"class":227},"] ",[149,400,401],{"class":198},"Copy file\n",[149,403,404,407,410,412,415,417,420,422],{"class":151,"line":181},[149,405,406],{"class":227},"   *[",[149,408,409],{"class":159},"other",[149,411,398],{"class":227},[149,413,414],{"class":198},"Copy ",[149,416,378],{"class":163},[149,418,419],{"class":159},"$count",[149,421,253],{"class":163},[149,423,424],{"class":198}," files\n",[149,426,427],{"class":151,"line":205},[149,428,214],{"class":163},[140,430,432],{"className":142,"code":431,"language":144,"meta":145,"style":145},"$t('copy-n-files', { count: 5 })\n",[14,433,434],{"__ignoreMap":145},[149,435,436,438,440,442,444,446,448,450,452,454,458,461],{"class":151,"line":152},[149,437,96],{"class":227},[149,439,230],{"class":159},[149,441,190],{"class":163},[149,443,187],{"class":198},[149,445,190],{"class":163},[149,447,239],{"class":163},[149,449,242],{"class":163},[149,451,245],{"class":173},[149,453,48],{"class":163},[149,455,457],{"class":456},"sYRBq"," 5",[149,459,460],{"class":163}," }",[149,462,256],{"class":159},[10,464,465],{},"This syntax can be used in any translation message to choose an option based on plural category, or even a concrete value.",[50,467,469],{"id":468},"_3-translators-dont-have-control-over-translations","3. Translators don't have control over translations",[10,471,472],{},"Developers are forced to make choices that translators should make: \"should translation message be pluralized?\", \"what date and number format to use?\".",[10,474,475],{},[127,476,477],{},[130,478,479],{},"Example (date format):",[10,481,482,484],{},[14,483,16],{}," has a fixed number of developer-predefined date formats and developer decides what format to use in each case.",[140,486,488],{"className":142,"code":487,"language":144,"meta":145,"style":145},"const dateTimeFormats = {\n  'en': {\n    short: {\n      year: 'numeric',\n      month: 'short',\n      day: 'numeric'\n    },\n    long: {\n      ...\n    }\n  }\n}\n\nconst messages = {\n  'en': {\n    'last-online': 'User was last online at {date}'\n  }\n}\n\n$t('last-online', { date: $d(new Date(), 'short') })\n",[14,489,490,501,515,524,541,557,570,575,585,591,597,602,607,612,623,636,655,660,665,670],{"__ignoreMap":145},[149,491,492,494,497,499],{"class":151,"line":152},[149,493,156],{"class":155},[149,495,496],{"class":159}," dateTimeFormats ",[149,498,164],{"class":163},[149,500,167],{"class":163},[149,502,503,506,509,511,513],{"class":151,"line":170},[149,504,505],{"class":163},"  '",[149,507,508],{"class":173},"en",[149,510,190],{"class":163},[149,512,48],{"class":163},[149,514,167],{"class":163},[149,516,517,520,522],{"class":151,"line":181},[149,518,519],{"class":173},"    short",[149,521,48],{"class":163},[149,523,167],{"class":163},[149,525,526,529,531,533,536,538],{"class":151,"line":205},[149,527,528],{"class":173},"      year",[149,530,48],{"class":163},[149,532,195],{"class":163},[149,534,535],{"class":198},"numeric",[149,537,190],{"class":163},[149,539,540],{"class":163},",\n",[149,542,543,546,548,550,553,555],{"class":151,"line":211},[149,544,545],{"class":173},"      month",[149,547,48],{"class":163},[149,549,195],{"class":163},[149,551,552],{"class":198},"short",[149,554,190],{"class":163},[149,556,540],{"class":163},[149,558,559,562,564,566,568],{"class":151,"line":217},[149,560,561],{"class":173},"      day",[149,563,48],{"class":163},[149,565,195],{"class":163},[149,567,535],{"class":198},[149,569,202],{"class":163},[149,571,572],{"class":151,"line":224},[149,573,574],{"class":163},"    },\n",[149,576,578,581,583],{"class":151,"line":577},8,[149,579,580],{"class":173},"    long",[149,582,48],{"class":163},[149,584,167],{"class":163},[149,586,588],{"class":151,"line":587},9,[149,589,590],{"class":163},"      ...\n",[149,592,594],{"class":151,"line":593},10,[149,595,596],{"class":163},"    }\n",[149,598,600],{"class":151,"line":599},11,[149,601,208],{"class":163},[149,603,605],{"class":151,"line":604},12,[149,606,214],{"class":163},[149,608,610],{"class":151,"line":609},13,[149,611,221],{"emptyLinePlaceholder":220},[149,613,615,617,619,621],{"class":151,"line":614},14,[149,616,156],{"class":155},[149,618,160],{"class":159},[149,620,164],{"class":163},[149,622,167],{"class":163},[149,624,626,628,630,632,634],{"class":151,"line":625},15,[149,627,505],{"class":163},[149,629,508],{"class":173},[149,631,190],{"class":163},[149,633,48],{"class":163},[149,635,167],{"class":163},[149,637,639,641,644,646,648,650,653],{"class":151,"line":638},16,[149,640,184],{"class":163},[149,642,643],{"class":173},"last-online",[149,645,190],{"class":163},[149,647,48],{"class":163},[149,649,195],{"class":163},[149,651,652],{"class":198},"User was last online at {date}",[149,654,202],{"class":163},[149,656,658],{"class":151,"line":657},17,[149,659,208],{"class":163},[149,661,663],{"class":151,"line":662},18,[149,664,214],{"class":163},[149,666,668],{"class":151,"line":667},19,[149,669,221],{"emptyLinePlaceholder":220},[149,671,673,675,677,679,681,683,685,687,690,692,695,697,700,703,706,708,710,712,714,717,719],{"class":151,"line":672},20,[149,674,96],{"class":227},[149,676,230],{"class":159},[149,678,190],{"class":163},[149,680,643],{"class":198},[149,682,190],{"class":163},[149,684,239],{"class":163},[149,686,242],{"class":163},[149,688,689],{"class":173}," date",[149,691,48],{"class":163},[149,693,694],{"class":227}," $d",[149,696,230],{"class":159},[149,698,699],{"class":163},"new",[149,701,702],{"class":227}," Date",[149,704,705],{"class":159},"()",[149,707,239],{"class":163},[149,709,195],{"class":163},[149,711,552],{"class":198},[149,713,190],{"class":163},[149,715,716],{"class":159},") ",[149,718,253],{"class":163},[149,720,256],{"class":159},[10,722,723],{},"Translators can't change date formatting for a particular translation, for example, if it doesn't fit into UI in some language.",[10,725,726],{},[127,727,728],{},[130,729,362],{},[10,731,732,733,736],{},"Fluent syntax allows translators to call custom function in translation messages. For date internationalization fluent-vue has a built-in ",[14,734,735],{},"DATETIME"," function:",[140,738,740],{"className":365,"code":739,"language":367,"meta":145,"style":145},"last-online = User was last online at { DATETIME($date, year: \"numeric\", month: \"short\", month: \"short\") }\n",[14,741,742],{"__ignoreMap":145},[149,743,744,747,750,752,755,758,760,763,766,768,771,774,776,778,780,783],{"class":151,"line":152},[149,745,746],{"class":374},"last-online = ",[149,748,749],{"class":198},"User was last online at ",[149,751,378],{"class":163},[149,753,754],{"class":227}," DATETIME(",[149,756,757],{"class":159},"$date",[149,759,239],{"class":227},[149,761,762],{"class":227}," year:",[149,764,765],{"class":159}," \"numeric\"",[149,767,239],{"class":227},[149,769,770],{"class":227}," month:",[149,772,773],{"class":159}," \"short\"",[149,775,239],{"class":227},[149,777,770],{"class":227},[149,779,773],{"class":159},[149,781,782],{"class":227},")",[149,784,785],{"class":163}," }\n",[140,787,789],{"className":142,"code":788,"language":144,"meta":145,"style":145},"$t('last-online', { date: new Date() })\n",[14,790,791],{"__ignoreMap":145},[149,792,793,795,797,799,801,803,805,807,809,811,814,816,819,821],{"class":151,"line":152},[149,794,96],{"class":227},[149,796,230],{"class":159},[149,798,190],{"class":163},[149,800,643],{"class":198},[149,802,190],{"class":163},[149,804,239],{"class":163},[149,806,242],{"class":163},[149,808,689],{"class":173},[149,810,48],{"class":163},[149,812,813],{"class":163}," new",[149,815,702],{"class":227},[149,817,818],{"class":159},"() ",[149,820,253],{"class":163},[149,822,256],{"class":159},[10,824,825],{},"If you want to have predefined date formats it can be implemented using a custom function. But translators will still be able to choose what format to use in each case.",[50,827,829],{"id":828},"_4-syntax-isnt-powerful-enough","4. Syntax isn't powerful enough",[10,831,832,833,835],{},"Even with ",[14,834,100],{}," method there is no way to have pluralization that depends on counts of 2 or more objects:",[140,837,839],{"className":142,"code":838,"language":144,"meta":145,"style":145},"$tc('apples-and-bananas', \u002F* what should go here? *\u002F, { appleCount: 1, bananaCount: 5 })\n\nconst messages = {\n  en: {\n    'apples-and-bananas': '{appleCount} apples and {bananaCount} bananas'\n  }\n}\n",[14,840,841,885,889,899,907,924,928],{"__ignoreMap":145},[149,842,843,845,847,849,852,854,856,860,862,864,867,869,872,874,877,879,881,883],{"class":151,"line":152},[149,844,100],{"class":227},[149,846,230],{"class":159},[149,848,190],{"class":163},[149,850,851],{"class":198},"apples-and-bananas",[149,853,190],{"class":163},[149,855,239],{"class":163},[149,857,859],{"class":858},"sWuyu"," \u002F* what should go here? *\u002F",[149,861,239],{"class":163},[149,863,242],{"class":163},[149,865,866],{"class":173}," appleCount",[149,868,48],{"class":163},[149,870,871],{"class":456}," 1",[149,873,239],{"class":163},[149,875,876],{"class":173}," bananaCount",[149,878,48],{"class":163},[149,880,457],{"class":456},[149,882,460],{"class":163},[149,884,256],{"class":159},[149,886,887],{"class":151,"line":170},[149,888,221],{"emptyLinePlaceholder":220},[149,890,891,893,895,897],{"class":151,"line":181},[149,892,156],{"class":155},[149,894,160],{"class":159},[149,896,164],{"class":163},[149,898,167],{"class":163},[149,900,901,903,905],{"class":151,"line":205},[149,902,174],{"class":173},[149,904,48],{"class":163},[149,906,167],{"class":163},[149,908,909,911,913,915,917,919,922],{"class":151,"line":211},[149,910,184],{"class":163},[149,912,851],{"class":173},[149,914,190],{"class":163},[149,916,48],{"class":163},[149,918,195],{"class":163},[149,920,921],{"class":198},"{appleCount} apples and {bananaCount} bananas",[149,923,202],{"class":163},[149,925,926],{"class":151,"line":217},[149,927,208],{"class":163},[149,929,930],{"class":151,"line":224},[149,931,214],{"class":163},[10,933,934],{},"One possible solution for this issue is splitting translation into three different ones. But is doesn't look particularly good:",[140,936,938],{"className":142,"code":937,"language":144,"meta":145,"style":145},"$t('apples-and-bananas', {\n  appleCountText: $tc('apples', 1, { appleCount: 1 }),\n  bananaCountText: $tc('banana', 5, { bananaCount: 5 })\n})\n\nconst messages = {\n  en: {\n    'apples-and-bananas': '{appleCountText} and {bananaCountText}',\n    'apples': '{appleCount} apple | {appleCount} apples',\n    'bananas': '{bananaCount} banana | {bananaCount} bananas'\n  }\n}\n",[14,939,940,956,995,1031,1037,1041,1051,1059,1078,1097,1115,1119],{"__ignoreMap":145},[149,941,942,944,946,948,950,952,954],{"class":151,"line":152},[149,943,96],{"class":227},[149,945,230],{"class":159},[149,947,190],{"class":163},[149,949,851],{"class":198},[149,951,190],{"class":163},[149,953,239],{"class":163},[149,955,167],{"class":163},[149,957,958,961,963,966,968,970,973,975,977,979,981,983,985,987,989,991,993],{"class":151,"line":170},[149,959,960],{"class":173},"  appleCountText",[149,962,48],{"class":163},[149,964,965],{"class":227}," $tc",[149,967,230],{"class":159},[149,969,190],{"class":163},[149,971,972],{"class":198},"apples",[149,974,190],{"class":163},[149,976,239],{"class":163},[149,978,871],{"class":456},[149,980,239],{"class":163},[149,982,242],{"class":163},[149,984,866],{"class":173},[149,986,48],{"class":163},[149,988,871],{"class":456},[149,990,460],{"class":163},[149,992,782],{"class":159},[149,994,540],{"class":163},[149,996,997,1000,1002,1004,1006,1008,1011,1013,1015,1017,1019,1021,1023,1025,1027,1029],{"class":151,"line":181},[149,998,999],{"class":173},"  bananaCountText",[149,1001,48],{"class":163},[149,1003,965],{"class":227},[149,1005,230],{"class":159},[149,1007,190],{"class":163},[149,1009,1010],{"class":198},"banana",[149,1012,190],{"class":163},[149,1014,239],{"class":163},[149,1016,457],{"class":456},[149,1018,239],{"class":163},[149,1020,242],{"class":163},[149,1022,876],{"class":173},[149,1024,48],{"class":163},[149,1026,457],{"class":456},[149,1028,460],{"class":163},[149,1030,256],{"class":159},[149,1032,1033,1035],{"class":151,"line":205},[149,1034,253],{"class":163},[149,1036,256],{"class":159},[149,1038,1039],{"class":151,"line":211},[149,1040,221],{"emptyLinePlaceholder":220},[149,1042,1043,1045,1047,1049],{"class":151,"line":217},[149,1044,156],{"class":155},[149,1046,160],{"class":159},[149,1048,164],{"class":163},[149,1050,167],{"class":163},[149,1052,1053,1055,1057],{"class":151,"line":224},[149,1054,174],{"class":173},[149,1056,48],{"class":163},[149,1058,167],{"class":163},[149,1060,1061,1063,1065,1067,1069,1071,1074,1076],{"class":151,"line":577},[149,1062,184],{"class":163},[149,1064,851],{"class":173},[149,1066,190],{"class":163},[149,1068,48],{"class":163},[149,1070,195],{"class":163},[149,1072,1073],{"class":198},"{appleCountText} and {bananaCountText}",[149,1075,190],{"class":163},[149,1077,540],{"class":163},[149,1079,1080,1082,1084,1086,1088,1090,1093,1095],{"class":151,"line":587},[149,1081,184],{"class":163},[149,1083,972],{"class":173},[149,1085,190],{"class":163},[149,1087,48],{"class":163},[149,1089,195],{"class":163},[149,1091,1092],{"class":198},"{appleCount} apple | {appleCount} apples",[149,1094,190],{"class":163},[149,1096,540],{"class":163},[149,1098,1099,1101,1104,1106,1108,1110,1113],{"class":151,"line":593},[149,1100,184],{"class":163},[149,1102,1103],{"class":173},"bananas",[149,1105,190],{"class":163},[149,1107,48],{"class":163},[149,1109,195],{"class":163},[149,1111,1112],{"class":198},"{bananaCount} banana | {bananaCount} bananas",[149,1114,202],{"class":163},[149,1116,1117],{"class":151,"line":599},[149,1118,208],{"class":163},[149,1120,1121],{"class":151,"line":604},[149,1122,214],{"class":163},[10,1124,1125],{},[127,1126,1127],{},[130,1128,362],{},[10,1130,1131],{},"Thanks to Fluent syntax you can write translation, without splitting it, like this:",[140,1133,1135],{"className":142,"code":1134,"language":144,"meta":145,"style":145},"$t('apples-and-bananas', { appleCount: 1, bananaCount: 5 })\n",[14,1136,1137],{"__ignoreMap":145},[149,1138,1139,1141,1143,1145,1147,1149,1151,1153,1155,1157,1159,1161,1163,1165,1167,1169],{"class":151,"line":152},[149,1140,96],{"class":227},[149,1142,230],{"class":159},[149,1144,190],{"class":163},[149,1146,851],{"class":198},[149,1148,190],{"class":163},[149,1150,239],{"class":163},[149,1152,242],{"class":163},[149,1154,866],{"class":173},[149,1156,48],{"class":163},[149,1158,871],{"class":456},[149,1160,239],{"class":163},[149,1162,876],{"class":173},[149,1164,48],{"class":163},[149,1166,457],{"class":456},[149,1168,460],{"class":163},[149,1170,256],{"class":159},[140,1172,1174],{"className":365,"code":1173,"language":367,"meta":145,"style":145},"apples-and-bananas = {$appleCount -> \n    [one] An apple\n   *[other] {$appleCount} apples\n} and {$bananaCount -> \n    [one] a banana\n   *[other] {$bananaCount} bananas\n}\n",[14,1175,1176,1190,1201,1219,1235,1246,1264],{"__ignoreMap":145},[149,1177,1178,1181,1183,1186,1188],{"class":151,"line":152},[149,1179,1180],{"class":374},"apples-and-bananas = ",[149,1182,378],{"class":163},[149,1184,1185],{"class":159},"$appleCount ",[149,1187,384],{"class":227},[149,1189,387],{"class":198},[149,1191,1192,1194,1196,1198],{"class":151,"line":170},[149,1193,392],{"class":227},[149,1195,395],{"class":159},[149,1197,398],{"class":227},[149,1199,1200],{"class":198},"An apple\n",[149,1202,1203,1205,1207,1209,1211,1214,1216],{"class":151,"line":181},[149,1204,406],{"class":227},[149,1206,409],{"class":159},[149,1208,398],{"class":227},[149,1210,378],{"class":163},[149,1212,1213],{"class":159},"$appleCount",[149,1215,253],{"class":163},[149,1217,1218],{"class":198}," apples\n",[149,1220,1221,1223,1226,1228,1231,1233],{"class":151,"line":205},[149,1222,253],{"class":163},[149,1224,1225],{"class":198}," and ",[149,1227,378],{"class":163},[149,1229,1230],{"class":159},"$bananaCount ",[149,1232,384],{"class":227},[149,1234,387],{"class":198},[149,1236,1237,1239,1241,1243],{"class":151,"line":211},[149,1238,392],{"class":227},[149,1240,395],{"class":159},[149,1242,398],{"class":227},[149,1244,1245],{"class":198},"a banana\n",[149,1247,1248,1250,1252,1254,1256,1259,1261],{"class":151,"line":217},[149,1249,406],{"class":227},[149,1251,409],{"class":159},[149,1253,398],{"class":227},[149,1255,378],{"class":163},[149,1257,1258],{"class":159},"$bananaCount",[149,1260,253],{"class":163},[149,1262,1263],{"class":198}," bananas\n",[149,1265,1266],{"class":151,"line":224},[149,1267,214],{"class":163},[1269,1270,1271],"style",{},"html pre.shiki code .smZ93, html code.shiki .smZ93{--shiki-light:#9C3EDA;--shiki-default:#9C3EDA;--shiki-dark:#C792EA}html pre.shiki code .sZSNi, html code.shiki .sZSNi{--shiki-light:#90A4AE;--shiki-default:#90A4AE;--shiki-dark:#BABED8}html pre.shiki code .sDfIl, html code.shiki .sDfIl{--shiki-light:#39ADB5;--shiki-default:#39ADB5;--shiki-dark:#89DDFF}html pre.shiki code .sRlkE, html code.shiki .sRlkE{--shiki-light:#E53935;--shiki-default:#E53935;--shiki-dark:#F07178}html pre.shiki code .sGFVr, html code.shiki .sGFVr{--shiki-light:#91B859;--shiki-default:#91B859;--shiki-dark:#C3E88D}html pre.shiki code .s3cPz, html code.shiki .s3cPz{--shiki-light:#6182B8;--shiki-default:#6182B8;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s52Pk, html code.shiki .s52Pk{--shiki-light:#E2931D;--shiki-default:#E2931D;--shiki-dark:#FFCB6B}html pre.shiki code .sYRBq, html code.shiki .sYRBq{--shiki-light:#F76D47;--shiki-default:#F76D47;--shiki-dark:#F78C6C}html pre.shiki code .sWuyu, html code.shiki .sWuyu{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#90A4AE;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":145,"searchDepth":170,"depth":170,"links":1273},[1274,1275],{"id":41,"depth":181,"text":42},{"id":77,"depth":181,"text":78},"2021-08-08T21:00:00.000+02:00","Problems I have encountered when trying to use vue-i18n library for internationalization of my app, and how fluent-vue solves them","5min","md","vue.js, vue, js, internationalization, vue i18n, localization",{},"\u002Fposts\u002Fvue-i18n-difficulties",{"title":5,"description":1277},"posts\u002F1.vue-i18n-difficulties","uxzSEc5dGD7_GkmSQvnXlfyDMu8xzks7OGQVX_eXydE",1779980047680]