![Create React App Officially Deprecated Amid React 19 Compatibility Issues](https://cdn.sanity.io/images/cgdhsj6q/production/04fa08cf844d798abc0e1a6391c129363cc7e2ab-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Create React App Officially Deprecated Amid React 19 Compatibility Issues
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
@volvo-cars/react-shared-translations
Advanced tools
React translation library that provides localized translation for packages
Questions? Ask in Slack #vcc-ui
@volvo-cars/react-shared-translations
This package is used as a wrapper for the @volvo-cars packages with i18n support. It serves translations for the locales included with the packages, mostly short UI labels required for accessibility reasons. It automatically serves translations with minimal effect on bundle size and performance. It supports both server-side and client-side rendering.
💡 This package includes Typescript definitions
Wrap your React application with a TranslatorProvider
and feed it the locale
and translator
props. On the server-side, the translator
will get the translations synchronously from JSON files included with npm packages. On the client-side, translator
will use a cache created by the server-side translator
if it exists. If it doesn't, translations will be fetched in runtime.
A complete example of implementing package translations in your Next.js app can be found here.
_document.tsx
import React from 'react';
import NextDocument, {
Html,
Head,
Main,
NextScript,
DocumentContext,
} from 'next/document';
import {
Translator,
TranslatorCache,
} from '@volvo-cars/react-shared-translations';
class Document extends NextDocument<{ translator: Translator }> {
static async getInitialProps(ctx: DocumentContext) {
const { renderPage } = ctx;
// Create a server translator which will hold the cache in translator.cache when the
// app finishes rendering
const translator = new Translator();
const originalRenderPage = renderPage;
// Modify renderPage and pass the translator to _app.tsx to be then passsed to the provider
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App: any) =>
function EnhancedApp(props) {
// ↓↓↓ pass the translator as a prop to _app.tsx
return <App {...props} translator={translator} />;
},
});
const initialProps = await NextDocument.getInitialProps(ctx);
return {
...initialProps,
// pass the translator as prop to Document to be used down below in render
translator,
};
}
render() {
const { translator } = this.props;
return (
<Html>
<Head />
<body>
{/*
Pass the translator to TranslatorCache to render the
Translator.cache to the HTML state
*/}
<TranslatorCache translator={translator} />
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default Document;
_app.tsx
import React from 'react';
import { NextComponentType } from 'next';
import Providers from 'src/Providers';
import { AppProps } from 'next/app';
import {
TranslatorProvider,
Translator,
} from '@volvo-cars/react-shared-translations';
// Create a browser translator to be used client-side
const browserTranslator = new Translator();
function App({
Component,
pageProps,
translator,
}: {
Component: NextComponentType;
pageProps: AppProps['pageProps'];
translator?: Translator;
}) {
return (
// Pass the translator and locale to TranslatorProvider
// translator is only defined server-side, so we add
// browserTranslator for the browser
<TranslatorProvider
locale="sv-SE"
translator={translator || browserTranslator}
>
<Component {...pageProps} />
</TranslatorProvider>
);
}
export default App;
server.tsx
import React from 'react';
import ReactDomServer from 'react-dom/server';
import express from 'express';
import App from './components/App.tsx';
import htmlTemplate from './build/index.html';
import {
Translator,
TranslatorCache,
} from '@volvo-cars/react-shared-translations';
const app = express();
const port = 3000;
app.get('/', (req, res) => {
const translator = new Translator();
const content = ReactDomServer.renderToString(
<App locale="sv-SE" translator={translator} />
);
const html = html.replace(
'<div id="root"></div>',
`${ReactDomServer.renderToString(
<TranslatorCache translator={translator} />
)}
<div id="root">${content}</div>`
);
res.send(html);
});
app.listen(port, () => {
console.info(`Listening on port ${port}`);
});
client.tsx
import React from 'react';
import ReactDOM from 'react-dom'
import App from './components/App.tsx';
import { TranslatorProvider, Translator } from '@volvo-cars/react-shared-translations';
const browserTranslator = new Translator();
ReactDOM.hydrate(
<App locale="sv-SE" translator={browserTranslator}/>
,document.getElementById('app');
)
App.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App.tsx';
import {
TranslatorProvider,
Translator,
} from '@volvo-cars/react-shared-translations';
const App: React.FC<{ translator: Translator; locale: string }> = ({
translator,
locale,
children,
}) => {
return (
<TranslatorProvider locale={locale} translator={translator}>
<div>My app</div>
</TranslatorProvider>
);
};
To avoid having to wait for translations to be asynchronasly import during
testing, we provided a MockedProvider
components that makes testing much
easier. It takes an optional mocks
prop of type Record<string, string>
, where the key is the key used by the packages interally, ex: react-faqs.showMore
. If mocks
is not provided, the key will be returned instead.
import { MockedProvider } from '@volvo-cars/react-shared-translations/testing';
import { render } from '@testing-library/react';
import { Breadcrumbs } from '@volvo-cars/react-breadcrumbs';
test('renders aria-label key when mocks are not provided', () => {
const { getByLabelText } = render(
<MockedProvider>
<Breadcrumbs
trail={[{ title: 'title', href: 'www' }]}
currentTitle="Current Title"
/>
</MockedProvider>
);
const label = getByLabelText('react-breadcrumbs.ariaLabel');
expect(label).toBeInTheDocument();
});
test('renders aria-label mocked value', () => {
const { getByLabelText } = render(
<MockedProvider mocks={{ 'react-breadcrumbs.ariaLabel': 'Breadcrumb' }}>
<Breadcrumbs
trail={[{ title: 'title', href: 'www' }]}
currentTitle="Current Title"
/>
</MockedProvider>
);
const label = getByLabelText('Breadcrumb');
expect(label).toBeInTheDocument();
});
The following section is for developers that work on @volvo-cars packages and want to localize strings in their packages.
A convention needs to be followed in the packages that will serve translated strings and it goes as follows:
useTranslate
hook must be called with packageName.itemKey
Ex:
const showMore = useTranslate('react-faqs.showMore');
We now know that the required string exists in the @volvo-cars/react-faqs
package in the showMore
item
Translation files must be inside a i18n
directory with ${locale}.json
as file names inside the package that needs them, Ex:
└── react-faqs/
├── i18n/
│ └── en.json
│ └── sv-SE.json
│ └── da-DK.json
│ └── en-US.json
useTranslate
takes an optional second argument that decides if the translation should happen or not:
const showMoreText = useTranslate('react-faqs.showMore', { disabled: true });
The above will return undefined
as long as disabled
is true
. This is to allow you to override the translation with
something else like a prop provided by the consumers of your package.
FAQs
React translation library that provides localized translation for packages
The npm package @volvo-cars/react-shared-translations receives a total of 0 weekly downloads. As such, @volvo-cars/react-shared-translations popularity was classified as not popular.
We found that @volvo-cars/react-shared-translations demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 8 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.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.