nanostores / i18n Goto Github PK
View Code? Open in Web Editor NEWA tiny (≈600 bytes) i18n library for React/Preact/Vue/Svelte
License: MIT License
A tiny (≈600 bytes) i18n library for React/Preact/Vue/Svelte
License: MIT License
Backport similar feature from Nano Stores Router nanostores/router#12
const { number, time } = useStore(format)
The documentation clearly says that they accept a second argument:
Lines 209 to 226 in 99d21a5
I'm hoping to do something like this...
import fs from 'fs';
import { i18n } from '@nanostores/i18n';
i18n.loadStatic({
'en-US': JSON.parse( fs.readFileSync('/path/to.en-US.json') ),
'de-DE': JSON.parse( fs.readFileSync('/path/to.de-DE.json') )
});
i18n( 'en-US' )( 'click_here' ); // Click Here!
thanks for any reply you may have
Now I18n downloads the whole translation JSON for specific locale.
get (locale) {
return fetch(`/translations/${locale}.json`)
}
But many application parts are rarely used. It could be nice to have tree-shaking analog.
For instance, we use components name like main/post
or settings/user
. Then during the rendering we will collect all components names and send them to get
. In this example, get
will load translation for translations/ru/main.json
and trabslations/settings/ru.json
get (locale, components) {
return Promise.all(
components
.map(name => name.split('/')[0])
.unique()
.map(chunk => fetch(`/translations/${locale}/${chunk}.json`))
)
}
I tried to put a demo with a working example in codesandbox
and stackblitz
, and in both cases I got Cannot use 'import.meta' outside a module
. is it possible to wrap this part in try/catch
?
It would be very nice to see an example for SSR with for example nextjs
I'm using SvelteKit, and so far it's working fine unless for 1 problem.
When refreshing the page, it always flashes the baseTranslation
before the current locale translation.
The locale is persisted on the localStorage using persistentAtom
.
I also added await translationsLoading(i18n)
but same result.
And i18n.loading.get()
always returning false
How should one generate list-using messages with nanostores/i18n? Is there another recommended way using nanostores/i18n?
// input_missing_params -> "Validation failed, missing fields: {fields}"
getMessage( messages, 'en-US', 'input_missing_params', { fields: [ 'email', 'name' ].join( ', ' ) } )
Languages I'm working with aren't affected by different list formats like these: https://github.com/jamesplease/i18n-list-generator.js
I am trying to change the language, but still the value of baseTranslation
is used.
Am I dong something wrong? This is my implementation:
import { createI18n, localeFrom, browser } from '@nanostores/i18n'
import { persistentAtom } from '@nanostores/persistent'
import { fetchJson } from 'fetch-json'
export const setting = persistentAtom<string | undefined>('locale', undefined)
export const locale = localeFrom(
setting,
browser({
available: ['en', 'pl'],
fallback: 'en',
}),
)
console.log(locale.get()) // logs en
export const i18n = createI18n(locale, {
async get(code) {
console.log('hello') // is never called
if (code === 'pl') {
return Promise.resolve({})
}
return fetchJson.get(`/translations/${code}.json`)
},
})
export const navigation = i18n('navigation', {
app: 'Aplikacja',
})
console.log(navigation.value?.app) // logs polish translation
Thank you!
Hello.
I'm using Preact
+ vite-plugin-ssr
and useStore
gives me an error:
TypeError: Cannot read properties of undefined (reading '__H')
So far, I haven't been able to figure out what the problem is. Maybe I'm doing something wrong.
Example
It would be great if anyone has any ideas
Thanks
https://github.com/nanostores/i18n/blob/main/create-i18n/index.js#L23-L41
this is the stacktrace that appears in my service
TypeError: Cannot read properties of undefined (reading 'split')
at file:///app/node_modules/@nanostores/i18n/create-i18n/index.js:68:34
at listener (file:///app/node_modules/nanostores/lifecycle/index.js:129:19)
at object.events.<computed>.reduceRight.shared (file:///app/node_modules/nanostores/lifecycle/index.js:17:58)
at Array.reduceRight (<anonymous>)
at file:///app/node_modules/nanostores/lifecycle/index.js:17:31
at Object.store.listen (file:///app/node_modules/nanostores/lifecycle/index.js:136:9)
here's the nanostores location where the error occurs https://github.com/nanostores/i18n/blob/main/create-i18n/index.js#L68
the error appears to be a consequence of this failing condition. if this condition is not true, t.component
is not defined and runtime error occurs when t.component.split('/')[0]
is used later in the script
if (process.env.NODE_ENV !== 'production') {
t.component = componentName
t.base = base
if (define.cache[baseLocale][componentName]) {
if (import.meta && (import.meta.hot || import.meta.webpackHot)) {
/* c8 ignore next 3 */
for (let i of define.cache) {
delete define.cache[i][componentName]
}
} else {
// eslint-disable-next-line no-console
console.warn(
`I18n component ${componentName} was defined multiple times. ` +
'It could lead to cache issues. Try to move i18n definition ' +
'from component’s render function.'
)
}
}
}
Trying to use this package with @nanostores/persistent
and cannot save language settings. My locale data is deleting after page refresh.
You can try to check the problem here:
https://si5dw.csb.app/
Source code:
https://codesandbox.io/s/nanostores-i18n-si5dw
count
/params
can be explicitly applied to a specific message in translation.
It will be nice to have global translation preprocessor applied to all messages. For instance, we can create screen size transform on top of it:
// components/send-to-user.jsx
import { size } from '@nanostores/i18n'
import { i18n } from '../stores/i18n.js'
export messages = i18n({
send: size({ // We need this wrap only for types, size() will return string in TS
big: 'Send message',
small: 'send'
}),
name: 'User name'
})
// translations/ru.json
{
"send": "Отправить", // Only single variant here
"name": { // In Russian we have variants in a different key
"big": "Имя пользователя",
"small": "Имя"
}
}
// stores/i18n.js
import { atom, onMount } from 'nanostores'
import { createI18n, sizePrerocessor } from '@nanostores/i18n'
const screenSize = atom('big')
onMount(screenSize, () => {
let media = window.matchMedia('(min-width: 600px)')
funciton check () {
screenSize.set(media.matches ? 'big' : 'small')
}
media.addEventListener('change', check)
() => {
media.removeEventListener('change', check)
}
})
size.setSource(screenSize)
export const i18n = createI18n(locale, {
get: …,
preprocessors: [
sizePrerocessor // I18n will listen for `size` and will re-build translations on `size.source` changes
]
})
const messages = i18n('post', {
a: {
b: {
c: 'deep value',
},
},
});
Is this a valid construct or not?
If not, it should be described in the documentation.
If valid, we should fix the work of the functions and fix the types:
Now it works, but TS is throwing an error:
Type '{ b: { c: string; }; }' is not assignable to type 'Translation'.
Object literal may only specify known properties, and 'b' does not exist in type 'TranslationFunction<any[], string | TranslationsJSON | TranslationFunction<any[], string | TranslationsJSON | TranslationFunction<any[], string | TranslationsJSON | TranslationFunction<any[], string | ... 1 more ... | TranslationFunction<...>>>>>'.(2322)
Also it doesn't work with functions:
const messages = i18n('post', {
a: {
b: {
c: count({
one: '{count} comment',
many: '{count} comments',
})
},
},
});
Uncaught TypeError: t.a.b.c is not a function
Now components will throw I18n component X was defined multiple times
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.