Open BjoernRave opened 4 years ago
Have you tried the example/simple from the branch where I`m working on? Where in your i18n is allLanguages specified? In mine its set to allLanguages: ['en', 'de'], I suppose it has to be allLanguages: ['es', 'en', 'pt']
I added the allLanguages: ['es', 'en', 'pt']
, but same result. I mean everything works for me now in dev, but it seems like there is something wrong there. Also I just deployed to ZEIT Now with @now/next@canary
, but in prod I can still see the translation keys, I can't in dev though
Can you try to use only these lines.
From your code you are exporting a new instance. In my code the getNextI18NextInstance is not exported at all. getNextI18NextInstance is a function wich accepts the runtimeConfig and returns the instance. Consume i18n only through the exports available.
const getNextI18NextInstance = (nextConfig: NextRuntimeConfig) => {
return new NextI18Next(nextConfig, {
browserLanguageDetection: false,
serverLanguageDetection: false,
partialBundledLanguages: false,
defaultLanguage: 'en',
otherLanguages: ['de', 'es', 'pt'],
lng: 'en',
allLanguages: ['en', 'de', 'es', 'pt']
});
};
export const {
appWithTranslation,
useTranslation,
withTranslation,
i18n
} = getNextI18NextInstance(getConfig());
export const NextI18NextInstance = getNextI18NextInstance(getConfig());
ah, so I shouldn't do const { t, i18n } = useTranslation()
, but instead import i18n
from the above file?
Tried the above code, no matter where I get i18n
from, i18n.languages
still only contains i18n.languages
Also very important for now is the setup of the public folder!
Only do public/locales/en public/locales/de
but not use static within public public ~/static~ /locales/en
yea I am using it as you say. My i18n.ts
file is not in the root of the project, but this shouldnt be a problem, or?
The import has always to grab the i18n either through a relative path import, alias etc. Do not use i18n-next... for that
this will work
import getNextI18NextInstance from '../i18n'; const { i18n, Link, useTranslation } = getNextI18NextInstance; --> do not call the function here with just destructure whats provided
const { t } = useTranslation(['common', 'footer']);
also import { useTranslation } from '../../../../i18n'; const { t } = useTranslation();
of course you have to adjust the path to i18n
To clarify things
most of the time you consume
export const { appWithTranslation, useTranslation, withTranslation, i18n } = getNextI18NextInstance(getConfig());
this is only relevant for _document export const NextI18NextInstance = getNextI18NextInstance(getConfig());
used like composeTestMiddleware(req, res)(nextI18NextMiddleware(NextI18NextInstance));
ah, so I do need to adjust my _document
for this to work properly?
Switching the language would be
import { useTranslation } from '../../../../i18n';
const { i18n, t } = useTranslation(); i18n.changeLanguage(languageCode);
You can find a reference to switching the lng here
In _document you need
export const composeTestMiddleware = (
req: IncomingMessage,
res: ServerResponse
) => (middlewares: Array<Handler<IncomingMessage, ServerResponse>>) => {
const handler: RequestHandler<IncomingMessage, ServerResponse> = compose(
middlewares
);
const done = () => {
Logger.log('done');
};
handler(req, res, _next => {
return done();
});
return handler;
};
export const instantiateTestMiddleware = (
req: IncomingMessage,
res: ServerResponse
) => {
composeTestMiddleware(req, res)(nextI18NextMiddleware(NextI18NextInstance));
};
And in getInitialProps the following, also here https://github.com/project-millipede/millipede-docs/blob/master/pages/_document.tsx
MillipedeDocument.getInitialProps = async (
ctx: DocumentContext
): Promise<InitialProps> => {
instantiateTestMiddleware(ctx.req, ctx.res);
// Resolution order
So in the End a crazy setup to keep simple things rolling. In my opinion next-i18next requires a massiv rewrite to make simplification a priority both for internal and API stuff.
I think you will figure it out, I mean you have two repos (the simple example and mine, a much larger one). In any case before integration in you project just try the example and deploy that with now. Everything should work out of the box
@gurkerl83 yea, that seems like a lot of things only to replace some functions with some strings.
I am hoping a bit on what @rdewolff was talking about here https://github.com/isaachinman/next-i18next/issues/274#issuecomment-582582444
but it was already working for me on dev without the things in _document
and now I tried to deploy it to ZEIT Now and it break the whole thing
Server side backend2020-02-06T13:18:06.086Z undefined ERROR Uncaught Exception {"errorType":"Error","errorMessage":"ENOENT: no such file or directory, scandir '/var/task/es'","code":"ENOENT","errno":-2,"syscall":"scandir","path":"/var/task/es","stack":["Error: ENOENT: no such file or directory, scandir '/var/task/es'"," at Object.readdirSync (fs.js:854:3)"," at getAllNamespaces (/var/task/frontend/node_modules/next-i18next-serverless/dist/commonjs/config/create-config.js:126:31)"," at _default (/var/task/frontend/node_modules/next-i18next-serverless/dist/commonjs/config/create-config.js:131:27)"," at new NextI18Next (/var/task/frontend/node_modules/next-i18next-serverless/dist/commonjs/index.js:61:46)"," at getNextI18NextInstance (/var/task/frontend/.next/serverless/pages/index.js:1556:10)"," at Object.QJBX (/var/task/frontend/.next/serverless/pages/index.js:1572:5)"," at __webpack_require__ (/var/task/frontend/.next/serverless/pages/index.js:31:31)"," at Module.Y7Z2 (/var/task/frontend/.next/serverless/pages/index.js:2537:66)"," at __webpack_require__ (/var/task/frontend/.next/serverless/pages/index.js:31:31)"," at Module.clG1 (/var/task/frontend/.next/serverless/pages/index.js:3151:22)"]}Unknown application error occurredError
He just asked the question for a more simplified solution. This really applies to this issue of serverless middleware. First in next-i18next are several dependencies uses e.g. express which is a complete different approach in terms how data flow. Also Next! There are things I like and certain things I hate. On thing what i dislike most is that they provided serverless and lambda far too early and made it a big promise, but backward compatibility fully missing.
Sorry missed one thing!
you need a file in the following directory, it can be an empty json
./public/locales/en/common.json
It should work now. This is a different topic and probably a bug in NOW itself
@gurkerl83 I have that file
It seems a problem how you use the i18n file in your index.(ts/js) file
Please ensure you have no static folder in you root directory
Maybe you can send a screenshot?
We can also do a quick skype with screen-sharing, my skype id is project-millipede
yea, would love to do a quick skype session, it's lunch time here now though, so maybe in 1 and a half hours? Btw I am german :)
Fine with me, have my week of, also German
Hi, trying to replicate the error, but so far with no success. I looked at the error closer...
Server side backend2020-02-06T13:18:06.086Z undefined ERROR Uncaught Exception {"errorType":"Error","errorMessage":"ENOENT: no such file or directory, scandir '/var/task/es'",
So the first part is a console log of mine in create-config.ts
console.log('Server side backend');
I do not log the directory chosen, but something is off because the filesystem tries to access '/var/task/es'.
'es' is your default language
but it has to be a full path with at least 'locales' mentioned. This is not the case. On the top of the init method the root dir gets a fallback (I think this was required because NOW has several phases when deploying the app and in one of them publicRuntimeConfig is null.
My guess is that something is blocking the runtimeConfig being set at all. If is not set probably the output of process.cwd() will result in '/var/task/' which is certainly the wrong folder the locales are.
let rootDir;
if (runtimeConfig != null && runtimeConfig.publicRuntimeConfig != null) {
rootDir = runtimeConfig.publicRuntimeConfig.rootDir;
} else {
rootDir = process.cwd();
}
So maybe I have to create a stronger condition, not just isServer() but also if runtimeConfig.publicRuntimeConfig != null
My
i18n.ts
file:With this
i18n.ts
file, language changing works, but when I log thei18n
object I only see the current language in thei18n.languages
array. If I use thei18n.ts
file from milipede-docs/master and only change the languages, I can't change languages at all, and the array is emptyMy next.config.js file:
Next.js Version: 9.2.2-canary.12 next-i18next-serverless Version: 1.1.135