Skip to content

Commit

Permalink
feat: use i18next plugin system to get the i18next instance.
Browse files Browse the repository at this point in the history
  • Loading branch information
felixmosh committed May 22, 2023
1 parent d3863d9 commit 2c60c1f
Show file tree
Hide file tree
Showing 46 changed files with 408 additions and 386 deletions.
31 changes: 17 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ $ npm install --save-dev i18next-hmr

## Usage

Add the plugin to your webpack config (or nextjs).
Add the plugin to your webpack config (or next.config.js).

<!-- prettier-ignore-start -->

```js
// webpack.config.js
const { I18NextHMRPlugin } = require('i18next-hmr/plugin');
const { I18NextHMRPlugin } = require('i18next-hmr/webpack');

module.exports = {
...
Expand All @@ -44,12 +44,22 @@ module.exports = {

```js
// i18next.config.js
const Backend = require('i18next-http-backend');
const i18next = require('i18next');
i18next.init(options, callback);
const { HMRPlugin } = require('i18next-hmr/plugin');

const instance = i18next.use(Backend); // http-backend is required for client side reloading

if (process.env.NODE_ENV !== 'production') {
const { applyClientHMR } = require('i18next-hmr/client');
applyClientHMR(i18next);
instance.use(new HMRPlugin({
client: typeof window !== 'undefined', // enabled client side HMR
server: typeof window === 'undefined' // enabled server side HMR
}));
}

instance.init(options, callback);

module.exports = instance;
```

<!-- prettier-ignore-start -->
Expand All @@ -58,13 +68,6 @@ if (process.env.NODE_ENV !== 'production') {
// server.js
const express = require('express');

const i18n = require('./i18n');

if (process.env.NODE_ENV !== 'production') {
const { applyServerHMR } = require('i18next-hmr/server');
applyServerHMR(i18n);
}

const port = process.env.PORT || 3000;

(async () => {
Expand All @@ -85,8 +88,8 @@ The lib will trigger [`i18n.reloadResources([lang], [ns])`](https://www.i18next.
⚠️ If your server side is bundled using Webpack, the lib will use the native HMR (if enabled), for it to work properly the lib must be **bundled**, therefore, you should specify the lib as not [external](https://webpack.js.org/configuration/externals/).
There are 2 ways to do that:

1. if you are using [webpack-node-externals](https://github.com/liady/webpack-node-externals) specify `i18next-hmr` in the [`whitelist`](https://github.com/liady/webpack-node-externals#optionswhitelist-).
2. use a relative path to `node_modules`, something like:
1. If you are using [webpack-node-externals](https://github.com/liady/webpack-node-externals) specify `i18next-hmr` in the [`whitelist`](https://github.com/liady/webpack-node-externals#optionswhitelist-).
2. (deprecated method) use a relative path to `node_modules`, something like:
```js
// server.entry.js
if (process.env.NODE_ENV !== 'production') {
Expand Down
2 changes: 1 addition & 1 deletion __tests__/loader.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const loader = require('../lib/loader');
const loader = require('../lib/webpack/loader');

describe('loader', () => {
let context;
Expand Down
2 changes: 1 addition & 1 deletion __tests__/server-hmr.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ jest.mock('../lib/trigger.js', () => {
return changedData;
});
const applyServerHMR = require('../lib/server-hmr');
const plugin = require('../lib/plugin');
const plugin = require('../lib/webpack/plugin');
const applyClientHMR = require('../lib/client-hmr');

function whenNativeHMRTriggeredWith(changedFiles) {
Expand Down
17 changes: 0 additions & 17 deletions examples/next-with-next-i18next-v11/pages/_app.js

This file was deleted.

73 changes: 0 additions & 73 deletions examples/next-with-next-i18next-v11/pages/index.js

This file was deleted.

36 changes: 0 additions & 36 deletions examples/next-with-next-i18next-v11/pages/second-page.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const HttpBackend = require('i18next-http-backend/cjs');
const { HMRPlugin } = require('i18next-hmr/plugin');

module.exports = {
// https://www.i18next.com/overview/configuration-options#logging
Expand All @@ -13,5 +14,11 @@ module.exports = {
},
}
: {}),
use: typeof window !== 'undefined' ? [HttpBackend] : [],
serializeConfig: false,
use:
process.env.NODE_ENV !== 'production'
? typeof window !== 'undefined'
? [HttpBackend, new HMRPlugin({ client: true })]
: [new HMRPlugin({ server: true })]
: [],
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ const path = require('path');
module.exports = {
i18n,
webpack(config, { isServer }) {
if (config.mode === 'development') {
const { I18NextHMRPlugin } = require('i18next-hmr/plugin');
if (!isServer && config.mode === 'development') {
const { I18NextHMRPlugin } = require('i18next-hmr/webpack');
config.plugins.push(
new I18NextHMRPlugin({
localesDir: path.resolve(__dirname, 'public/locales'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
"start": "next start -p ${PORT:=3000}"
},
"dependencies": {
"i18next": "^22.5.0",
"i18next-http-backend": "^1.4.1",
"next": "12.2.2",
"next-i18next": "11.2.2",
"next-i18next": "13.2.2",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-dom": "18.2.0"
"react-dom": "18.2.0",
"react-i18next": "^12.3.1"
},
"devDependencies": {
"i18next-hmr": "^1.8.0"
"i18next-hmr": "^2.0.0"
}
}
7 changes: 7 additions & 0 deletions examples/next-with-next-i18next-v13/pages/_app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { appWithTranslation } from 'next-i18next';
import nextI18NextConfig from '../next-i18next.config';

const MyApp = ({ Component, pageProps }) => <Component {...pageProps} />;

// https://github.com/i18next/next-i18next#unserialisable-configs
export default appWithTranslation(MyApp, nextI18NextConfig);
73 changes: 73 additions & 0 deletions examples/next-with-next-i18next-v13/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import Link from 'next/link';
import { useRouter } from 'next/router';

import { useTranslation, Trans } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

import { Header } from '../components/Header';
import { Footer } from '../components/Footer';

const Homepage = () => {
const router = useRouter();
const { t } = useTranslation('common');

return (
<>
<main>
<Header heading={t('h1')} title={t('title')} />
<div style={{ display: 'inline-flex', width: '90%' }}>
<div style={{ width: '50%' }}>
<h3 style={{ minHeight: 70 }}>{t('blog.optimized.question')}</h3>
<p>
<Trans i18nKey="blog.optimized.answer">
Then you may have a look at{' '}
<a href="https://locize.com/blog/next-i18next/">this blog post</a>.
</Trans>
</p>
<a href="https://locize.com/blog/next-i18next/">
<img
style={{ width: '50%' }}
src="https://locize.com/blog/next-i18next/next-i18next.jpg"
/>
</a>
</div>
<div style={{ width: '50%' }}>
<h3 style={{ minHeight: 70 }}>{t('blog.ssg.question')}</h3>
<p>
<Trans i18nKey="blog.ssg.answer">
Then you may have a look at{' '}
<a href="https://locize.com/blog/next-i18n-static/">this blog post</a>.
</Trans>
</p>
<a href="https://locize.com/blog/next-i18n-static/">
<img
style={{ width: '50%' }}
src="https://locize.com/blog/next-i18n-static/title.jpg"
/>
</a>
</div>
</div>
<hr style={{ marginTop: 20, width: '90%' }} />
<div>
<Link href="/" locale={router.locale === 'en' ? 'de' : 'en'}>
<button>
{t('change-locale', { changeTo: router.locale === 'en' ? 'de' : 'en' })}
</button>
</Link>
<Link href="/second-page">
<button type="button">{t('to-second-page')}</button>
</Link>
</div>
</main>
<Footer />
</>
);
};

export const getStaticProps = async ({ locale }) => ({
props: {
...(await serverSideTranslations(locale, ['common', 'footer'])),
},
});

export default Homepage;
31 changes: 31 additions & 0 deletions examples/next-with-next-i18next-v13/pages/second-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Link from 'next/link';

import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

import { Header } from '../components/Header';
import { Footer } from '../components/Footer';

const SecondPage = () => {
const { t } = useTranslation('second-page');

return (
<>
<main>
<Header heading={t('h1')} title={t('title')} />
<Link href="/">
<button type="button">{t('back-to-home')}</button>
</Link>
</main>
<Footer />
</>
);
};

export const getStaticProps = async ({ locale }) => ({
props: {
...(await serverSideTranslations(locale, ['second-page', 'footer'])),
},
});

export default SecondPage;
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"description": "This is a non-page component that requires its own namespace"
}
}
Loading

0 comments on commit 2c60c1f

Please sign in to comment.