Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@vocab/react
Advanced tools
Vocab is a strongly typed internationalization framework for React.
Vocab is a monorepo with different packages you can install depending on your usage, the below list will get you started using the cli, React and webpack integrations.
$ npm i --save @vocab/cli @vocab/react @vocab/webpack
Before starting to write code you'll need to setup webpack to understand how to use translation.json
files.
This is done using the VocabWebpackPlugin.
webpack.config.js
const VocabWebpackPlugin = require('@vocab/webpack').default;
module.exports = {
...,
plugins: [new VocabWebpackPlugin({})]
}
You can configure Vocab directly when calling the API or via a vocab.config.js
file.
In this example we've configured two languages, English and French, where our initial translation.json
files will use English.
vocab.config.js
module.exports = {
devLanguage: 'en',
languages: [{ name: 'en' }, { name: 'fr' }]
};
Vocab doesn't tell you how to select or change your language. You just need to tell Vocab what language to use.
Note: Using methods discussed later we'll make sure the first language is loaded on page load. However, after this, changing languages may then lead to a period of no translations as Vocab downloads the new language's translations.
src/App.tsx
import { VocabProvider } from '@vocab/react';
function App({ children }) {
return (
<VocabProvider language={language}>
{children}
</VocabProvider>
);
}
A translation file is a JSON file consisting of a flat structure of keys, each with a message and an optional description.
Note: Currently, to create a new translation it must be placed inside a folder ending in .vocab
, this folder suffix can be configured with the translationsDirectorySuffix
configuration value.
./example.vocab/translations.json
{
"my key": {
"message": "Hello from Vocab",
"description": "An optional description to help when translating"
}
}
Then run vocab compile
. Or vocab compile --watch
.
This will create a new index.ts
file for each folder ending in .vocab
.
You can then import these translations into your React components. Translations can be used by calling the t
function returned by useTranslations
.
./MyComponent.tsx
import { useTranslations } from '@vocab/react';
import translations from './example.vocab';
function MyComponent({ children }) {
const { t } = useTranslations(translations);
return <div>{t('my key')}</div>;
}
So far, your app will run, but you're missing any translations other than the initial language. The below file can be created manually; however, you can also integrate with a remote translation platform to push and pull translations automatically. See External translation tooling for more information.
./example.vocab/fr-FR.translations.json
{
"my key": {
"message": "Bonjour de Vocab",
"description": "An optional description to help when translating"
}
}
Using the above method without optimizing what chunks webpack uses you may find the page needing to do an extra round trip to load languages on a page.
This is where getChunkName
can be used to retrieve the Webpack chunk used for a specific language.
For example, here is a Server Render function that would add the current language chunk to Loadable component's ChunkExtractor.
src/render.tsx
import { getChunkName } from '@vocab/webpack/chunk-name';
// ...
const chunkName = getChunkName(language);
const extractor = new ChunkExtractor();
extractor.addChunk(chunkName);
Translation messages can sometimes contain dynamic values, such as dates/times, links or usernames. These values can often exist somewhere in the middle of a message and change location based on translation.
To support this Vocab uses [Format.js's intl-messageformat] allowing you to use ICU Message syntax in your messages.
In the below example we use two messages, one that passes in a single parameter and one uses a component.
{
"my key with param": {
"message": "Bonjour de {name}"
},
"my key with component": {
"message": "Bonjour de <Link>Vocab</Link>"
}
}
Vocab will automatically parse these strings as ICU messages, identify the required parameters and ensure TypeScript knows the values must be passed in.
t('my key with param', {name: 'Vocab'});
t('my key with component', {Link: children => (<a href="/foo">{children}</Link>)});
Configuration can either be passed into the Node API directly or be gathered from the nearest vocab.config.js file.
vocab.config.js
module.exports = {
devLanguage: 'en',
languages: [
{ name: 'en' },
{ name: 'en-AU', extends: 'en' },
{ name: 'en-US', extends: 'en' },
{ name: 'fr-FR' }
],
/**
* The root directory to compile and validate translations
* Default: Current working directory
*/
projectRoot: ['./example/'];
/**
* A custom suffix to name vocab translation directories
* Default: '.vocab'
*/
translationsDirectorySuffix: '.vocab',
/**
* An array of glob paths to ignore from compilation and validation
*/
ignore: ['**/ignored_directory/**']
};
If you need to use Vocab outside of React, you can access the returned Vocab file directly. You'll then be responsible for when to load translations and how to update on translation load.
getMessages(language: string) => Promise<Messages>
returns messages for the given language formatted according to the correct locale. If the language has not been loaded it will load the language before resolving.Note: To optimize loading time you may want to call load
(see below) ahead of use.
load(language: string) => Promise<void>
attempts to pre-load messages for the given language. Resolving once complete. Note this only ensures the language is available and does not return any translations.getLoadedMessages(language: string) => Messages | null
returns messages for the given language formatted according to the correct locale. If the language has not been loaded it will return null
. Note that this will not load the language if it's not available. Useful when a synchronous (non-promise) return is required.Example: Promise based formatting of messages
import translations from './.vocab';
async function getFooMessage(language) {
let messages = await translations.getMessages(language);
return messages['my key'].format();
}
getFooMessage().then((m) => console.log(m));
Example: Synchronously returning a message
import translations from './.vocab';
function getFooMessageSync(language) {
let messages = translations.getLoadedMessages(language);
if (!messages) {
// Translations not loaded, start loading and return null for now
translations.load();
return null;
}
return messages.foo.format();
}
translations.load();
const onClick = () => {
console.log(getFooMessageSync());
};
Vocab generates custom index.ts
files that give your React components strongly typed translations to work with.
To generate these files run:
$ vocab compile
Or to re-run the compiler when files change use:
$ vocab compile --watch
Vocab can be used to synchronize your translations with translations from a remote translation platform.
Platform | Environment Variables |
---|---|
Phrase | PHRASE_PROJECT_ID, PHRASE_API_TOKEN |
$ vocab push --branch my-branch
$ vocab pull --branch my-branch
When running in Node.js the locale formatting is supported by Node.js's Internationalization support. Node.js will silently switch to the closest locale it can find if the passed locale is not available. See Node's documentation on Options for building Node.js for information on ensuring Node has the locales you need.
MIT.
FAQs
Vocab is a strongly typed internationalization framework for React.
The npm package @vocab/react receives a total of 2,437 weekly downloads. As such, @vocab/react popularity was classified as popular.
We found that @vocab/react demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.