Skip to content

Commit

Permalink
Add reloadOnPrerender option to reload resources in serverSideTrans…
Browse files Browse the repository at this point in the history
…lations so that developers don't have to restart their server when making changes to their translation JSON files (#1359)

* feat: add reloadOnPrerender option to reload resources

* tests: add tests for reloadOnPrerender

* linter: remove semicolons

Co-authored-by: Isaac Hinman <[email protected]>
  • Loading branch information
dcporter44 and isaachinman authored Sep 1, 2021
1 parent 197c3cf commit 2c08b29
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 0 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,14 @@ export const getStaticProps = async ({ locale }) => ({
});
```

#### Reloading Resources in Development

Because resources are loaded once when the server is started, any changes made to your translation JSON files in development will not be loaded until the server is restarted.

In production this does not tend to be an issue, but in development you may want to see updates to your translation JSON files without having to restart your development server each time. To do this, set the `reloadOnPrerender` config option to `true`.

This option will reload your translations whenever `serverSideTranslations` is called (in `getStaticProps` or `getServerSideProps`). If you are using `serverSideTranslations` in `getServerSideProps`, it is recommended to disable `reloadOnPrerender` in production environments as to avoid reloading resources on each server call.

#### Options

| Key | Default value |
Expand All @@ -221,6 +229,7 @@ export const getStaticProps = async ({ locale }) => ({
| `localeExtension` | `'json'` |
| `localePath` | `'./public/locales'` |
| `localeStructure` | `'{{lng}}/{{ns}}'` |
| `reloadOnPrerender` | `false` |
| `serializeConfig` | `true` |
| `strictMode` | `true` |
| `use` (for plugins) | `[]` |
Expand Down
1 change: 1 addition & 0 deletions src/config/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const defaultConfig = {
react: {
useSuspense: true,
},
reloadOnPrerender: false,
serializeConfig: true,
strictMode: true,
use: [],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,41 @@
import React from 'react'
import fs from 'fs'
import { UserConfig } from './types'
import { serverSideTranslations } from './serverSideTranslations'
import { globalI18n } from './appWithTranslation'
import { renderToString } from 'react-dom/server'
import { appWithTranslation } from './appWithTranslation'

jest.mock('fs', () => ({
existsSync: jest.fn(),
readdirSync: jest.fn(),
}))

const DummyApp = appWithTranslation(() => (
<div>Hello world</div>
))

const props = {
pageProps: {
_nextI18Next: {
initialLocale: 'en',
userConfig: {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},
},
},
} as any,
} as any

const renderDummyComponent = () =>
renderToString(
<DummyApp
{...props}
/>,
)

describe('serverSideTranslations', () => {
beforeEach(() => {
(fs.existsSync as jest.Mock).mockReturnValueOnce(false);
Expand Down Expand Up @@ -163,4 +192,40 @@ describe('serverSideTranslations', () => {
},
})
})

it('calls reloadResources when reloadOnPrerender option is true', async () => {
renderDummyComponent()

if (globalI18n) {
globalI18n.reloadResources = jest.fn()
}

await serverSideTranslations('en-US', [], {
i18n: {
defaultLocale: 'en-US',
locales: ['en-US', 'fr-CA'],
},
reloadOnPrerender: true,
} as UserConfig)

expect(globalI18n?.reloadResources).toHaveBeenCalledTimes(1)
})

it('does not call reloadResources when reloadOnPrerender option is false', async () => {
renderDummyComponent()

if (globalI18n) {
globalI18n.reloadResources = jest.fn()
}

await serverSideTranslations('en-US', [], {
i18n: {
defaultLocale: 'en-US',
locales: ['en-US', 'fr-CA'],
},
reloadOnPrerender: false,
} as UserConfig)

expect(globalI18n?.reloadResources).toHaveBeenCalledTimes(0)
})
})
7 changes: 7 additions & 0 deletions src/serverSideTranslations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import path from 'path'
import { createConfig } from './config/createConfig'
import createClient from './createClient'

import { globalI18n } from './appWithTranslation'

import { UserConfig, SSRConfig } from './types'
import { FallbackLng } from 'i18next'

Expand Down Expand Up @@ -60,8 +62,13 @@ export const serverSideTranslations = async (
localeExtension,
localePath,
fallbackLng,
reloadOnPrerender,
} = config

if (reloadOnPrerender) {
await globalI18n?.reloadResources()
}

const { i18n, initPromise } = createClient({
...config,
lng: initialLocale,
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type UserConfig = {
localeExtension?: string
localePath?: string
localeStructure?: string
reloadOnPrerender?: boolean
serializeConfig?: boolean
strictMode?: boolean
use?: any[]
Expand Down

1 comment on commit 2c08b29

@vercel
Copy link

@vercel vercel bot commented on 2c08b29 Sep 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.