我用Next.js + react-i18next建立了一个网站。
我发现该网站将在首次加载时重新加载。它实际上并没有通过浏览器重新加载,就像该元素突然隐藏并突然显示)
我尝试禁用服务器端CSS(_document.js的样式组件),并且页面将呈现为渲染后加载的CSS。然后,我尝试禁用i18Next(删除i18NextProvider并在页面中不使用i18n),该页面没有重新加载问题。因此,我认为i18Next中的问题触发了服务器端渲染和客户端渲染之间的重新加载。
所有API都将在服务器端被调用,因此我认为服务器端渲染的代码已经很完美了。所以我有一些想法可以解决这个问题,但是我不知道该怎么办。
1)首次加载时阻止客户端渲染 2)仅更新服务器端和客户端之间的差异,而不重新加载整个容器
这是我的文件。
server.js
// @flow weak
const express = require('express')
const path = require('path')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev, dir: './src' })
const handle = app.getRequestHandler()
const i18nextMiddleware = require('i18next-express-middleware')
const Backend = require('i18next-node-fs-backend')
const i18n = require('./i18n')
const i18nCallBack = () => {
app.prepare().then(() => {
const server = express()
server.use(i18nextMiddleware.handle(i18n))
server.use('/locales', express.static(path.join(__dirname, '/locales')))
server.get('*', (req, res) => {
handle(req, res)
})
return server.listen(3000, err => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})
}
i18n
.use(Backend)
.use(i18nextMiddleware.LanguageDetector)
.init(
{
fallbackLng: 'zh',
preload: ['zh', 'en'],
ns: ['common', 'menu', 'card', 'welcome'],
backend: {
allowMultiLoading: false,
loadPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.json'),
addPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.missing.json')
}
},
i18nCallBack
)
module.exports = i18nCallBack
i18n.js
// @flow strict
const i18n = require('i18next')
const XHR = require('i18next-xhr-backend')
const LanguageDetector = require('i18next-browser-languagedetector')
const options = {
fallbackLng: 'zh',
lng: 'zh',
load: 'languageOnly',
ns: ['common'],
defaultNS: 'common',
debug: false,
saveMissing: true,
interpolation: {
escapeValue: false,
formatSeparator: ',',
format: (value, format) => {
if (format === 'uppercase') return value.toUpperCase()
return value
}
},
preload: ['en', 'zh']
}
// $FlowFixMe
if (process.browser) {
i18n.use(XHR).use(LanguageDetector)
}
if (!i18n.isInitialized) i18n.init(options)
/* eslint-disable fp/no-mutation */
i18n.getInitialProps = (req, namespaces) => {
let nss = namespaces
if (!namespaces) nss = i18n.options.defaultNS
if (typeof nss === 'string') nss = [nss]
req.i18n.toJSON = () => null
const initialI18nStore = {}
req.i18n.languages.forEach(l => {
initialI18nStore[l] = {}
nss.forEach(ns => {
initialI18nStore[l][ns] =
(req.i18n.services.resourceStore.data[l] || {})[ns] || {}
})
})
return {
i18n: req.i18n,
initialI18nStore,
initialLanguage: req.i18n.language
}
}
/* eslint-enable fp/no-mutation */
module.exports = i18n