Reputation: 1891
I'm trying to implement multi language on server and client side. Everything is work .. I have problem only client side changing language on production (on localhost it works because it does not have prefix path)
on localhost url is http://localhost:3000
on prod url is http://example.com/someprefix
Problem When I click changing language button the url go to http://example.com/th/someprefix that is wrong I don't know why i18n route to this .. the correct is http://example.com/someprefix/th
This is my next.config.js I use assetPrefix = http://example.com/someprefix on Production
const { parsed: localEnv } = require('dotenv').config({
path: __dirname + `/.env.${process.env.NODE_ENV}`
});
const webpack = require('webpack');
const withImages = require('next-images');
const production = process.env.NODE_ENV === 'production';
const prefix = 'http://example.com/someprefix';
module.exports = withImages({
assetPrefix: production ? prefix : '',
plugins: [new webpack.EnvironmentPlugin(localEnv)],
webpack: (config, { isServer }) => {
// Fixes npm packages that depend on `fs` module
if (!isServer) {
config.node = {
fs: 'empty',
net: 'empty',
tls: 'empty'
};
}
return config;
}
});
I have the button for changing language (Client side) I use i18n.changeLanguage
...
<button type="button" onClick={() => i18n.changeLanguage('en')}>
change lang client side EN
</button>
<button type="button" onClick={() => i18n.changeLanguage('th')}>
change lang client side TH
</button>
...
MyPage.getInitialProps = async props => {
const { isServer } = props.ctx;
if (isServer) {
// called on server
} else {
// called on client
}
return { isServer, namespacesRequired: ['common', 'footer'] };
};
export default withTranslation('common')(MyPage);
This is i18n.js
const NextI18Next = require("next-i18next").default;
const production = process.env.NODE_ENV === 'production';
module.exports = new NextI18Next({
defaultLanguage: "th",
otherLanguages: ["en"],
defaultNS: ["common"],
//SSR
//myapp.com ---> Homepage in defaultLanguage
//myapp.com/en ---> Homepage in English
localeSubpaths: {
th: production ? 'th': 'th',
en: production ? 'en': 'en'
},
// workaround until next-i18next support public path
// https://github.com/isaachinman/next-i18next/issues/523
localePath: typeof window === "undefined" ? "public/locales" : "someprefix/locales"
});
This is server.js
const express = require('express');
const next = require('next');
const bodyParser = require('body-parser');
const routeApi = require('./router/index');
const nextI18NextMiddleware = require('next-i18next/middleware').default
const nextI18next = require('../i18n')
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler(app);
const PORT = process.env.PORT || 3000;
app
.prepare()
.then(() => {
const server = express();
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));
server.use('/api', routeApi);
server.use(nextI18NextMiddleware(nextI18next))
server.get('*', (req, res) => {
return handle(req, res);
});
server.listen(PORT, err => {
if (err) throw err;
console.info(`> 🚀 Server ready at http://localhost:${PORT}`);
});
})
.catch(ex => {
console.error(ex.stack);
process.exit(1);
});
This is my package.json
{
"name": "test",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "NODE_ENV=development node server/index.js",
"devwindow": "set NODE_ENV=development&&node server/index.js",
"build": "next build",
"start": "NODE_ENV=production node server/index.js",
"cypress:open": "cypress open",
"cypress:run": "cypress run"
},
"dependencies": {
"axios": "^0.19.0",
"babel-plugin-istanbul": "^5.2.0",
"body-parser": "^1.19.0",
"bootstrap": "^4.4.0",
"dotenv": "^8.2.0",
"es6-promise": "^4.2.8",
"express": "^4.17.1",
"form-data": "^3.0.0",
"formik": "^2.0.6",
"isomorphic-unfetch": "^3.0.0",
"jsonwebtoken": "^8.5.1",
"jwks-rsa": "^1.6.0",
"next": "9.1.4",
"next-i18next": "^2.1.1",
"next-images": "^1.2.0",
"next-redux-saga": "^4.1.2",
"next-redux-wrapper": "^4.0.1",
"qs": "^6.9.1",
"rc-progress": "^2.5.2",
"react": "16.12.0",
"react-bootstrap": "^1.0.0-beta.16",
"react-dom": "16.12.0",
"react-icons": "^3.8.0",
"react-redux": "^7.1.3",
"redux": "^4.0.4",
"redux-saga": "^1.1.3",
"styled-components": "^4.4.1",
"url-parse": "^1.4.7",
"yup": "^0.27.0"
},
"devDependencies": {
"@babel/cli": "^7.7.4",
"@babel/core": "^7.7.4",
"@babel/node": "^7.7.4",
"@babel/plugin-transform-runtime": "^7.7.4",
"@babel/preset-env": "^7.7.4",
"@babel/runtime": "^7.7.4",
"@cypress/code-coverage": "^1.10.4",
"babel-eslint": "^10.0.3",
"babel-plugin-styled-components": "^1.10.6",
"babel-plugin-transform-remove-console": "^6.9.4",
"cypress": "^3.7.0",
"eslint": "^6.7.1",
"eslint-plugin-react": "^7.16.0",
"istanbul-lib-coverage": "^2.0.5",
"nodemon": "^2.0.1",
"nyc": "^14.1.1",
"redux-devtools-extension": "^2.13.8"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Upvotes: 1
Views: 2129
Reputation: 35483
It is not related to next
but to next-i18next
.
From the source-code of it, the Link component that this lib supply is the one that "fixes" the urls, here.
So, you can see that lngPathCorrector
is not supports serving next app under some path.
You are welcome to make a PR for that.
Upvotes: 1