Currently, I have dynamic routes that should follow the pattern:
/client/[id]/edit
I honestly don't know what [id] is here. I can't predict them. Therefore, using
export const getStaticProps = async ({ locale }) => ({
props: {
...(await serverSideTranslations(locale, ["common"])),
},
});
will force me to use
export const getStaticPaths = async () => {
return {
paths: [], //indicates that no page needs be created at build time
fallback: true, //indicates the type of fallback
};
};
But I have no idea what paths can be. If I change it to something like paths: ['/client/*/edit'] or any variation to make * part a wildcard, nextjs will complain that it Error: ReactDOMServer does not yet support Suspense. (obviously).
My question is: how can I go around this issue? I honestly don't want to have SSG (this is expected by business and it is fine), but I want to use translations.
"next-i18next": "^8.0.2"
I am considering this repository's basic setup was made (README was followed).
Create a page like:
pages/[id]/index.tsx
As a sample, use the following page component:
import {useState} from 'react'
import { useRouter } from 'next/router'
const MyPage = () => {
const [item, setItem] = useState();
const { query: { id } } = useRouter();
// not really important
const fetchItem = (id:string) => {window.fetch(`/item/${id}`).then(data => data.json()).then(item => setItem(item))}
return item ? (
<div>
{item.name}
</div>
) : <span>loading...</span>
}
// Here I have to use getStaticProps for the i18n to work
export const getStaticProps = async ({ locale }) => ({
props: {
...(await serverSideTranslations(locale, ["common"])),
},
});
// Because I used getStaticProps, I am forced to use getStaticPaths.
// I don't know what [id] can be. This is a dynamic value coming from BE.
export const getStaticPaths = async () => {
return {
paths: [], //indicates that no page needs be created at build time
fallback: true, //indicates the type of fallback
};
};
Now, if you run the very basic nextjs-typescript project, nextjs will complaint it can't generate the static paths, because there are none. But, also, I don't really care about the paths, since they are dynamically coming from BE.
To work without the SSG option
I was having the exact same issue. I was also skipping the static generation by returning { paths: [], fallback: true }. This worked fine but whenever I then visit the site under /1234 I see that the props are being retrieved (1234.json is downloaded), but the content of the translation is empty:
{
"pageProps": {
"_nextI18Next": {
"initialI18nStore": {
"en": {
"common": {},
"footer": {}
}
},
"initialLocale": "en",
"userConfig": {
}
}
},
"__N_SSG": true
}
I already created a reproduction case based on the next-i18next sample:
https://github.com/TKone7/next-i18next/tree/master/examples/simple
It is deployed on vercel:
https://repro-dynamic-routing-c0737olgy-tkone7.vercel.app/de/1234
Meanwhile, I moved back to next 10.0.5 and nextjs-i18next 7.0.0
@TKone7
@TKone7 I don't see any issues with the repo you've linked at all. What you seem to be observing is the fallback page behaviour. If I add this to your [id]/index.js file:
if (isFallback) {
return null
}
The behaviour seems a bit more acceptable. Are you aware of how fallback and fallback page replacement works? It sounds like what you're after is probably SSR, via getServerSideProps. Otherwise, you'll need to actually set up a fallback page.
@pablohpsilva Also, my suggestion is to either use fallback the way it was intended, or use SSR.
Let me know if I can help in any other way!
Hi @isaachinman, thanks a lot for your response.
I am affraid, I think I explained myself not clearly. I adapted the repo to make it clear. Repro: https://repro-dynamic-routing-tkone7.vercel.app/blog/blog-post
When you visit the url /blog/blog-post (which is one of the declared paths) you see that the heading and buttons are translated. As soon as you visit a path that's not returned by getStaticPaths (e.g. /blog/new) the fallback is shown (since fallback: true). However, according to the vercel documentation, in the background the 'missing' page should be generated including the execution of getStaticProps. I can observe this behaviour in the browser's network tab, however the JSON returned containing the props does not contain any translations. See here:
{ "pageProps": { "_nextI18Next": { "initialI18nStore": { "en": { "common": {}, "footer": {} } }, "initialLocale": "en", "userConfig": { } } }, "__N_SSG": true }
I did a little more analysis of the working of the function serverSideTranslations. I see that in order to generate the static props it uses the file located in localePath, which is ./public/locales per default. This folder is available during build time, however once the deployment is completed those files are no longer available, causing the re-execution of getStaticProps to return empty translations.
@TKone7 That again sounds like the fault of whichever serverless platform you are using. You will need to ensure that your locale data remains in the filesystem.
Thanks for that hint, @isaachinman.
Found this article that presents a solution that works for the Vercel platform. Just adapt the file next-i18next.config.js as follows:
const path = require('path')
module.exports = {
ns: ['common', 'footer', 'second-page'],
i18n: {
defaultLocale: 'en',
locales: ['en', 'de'],
},
localePath: path.resolve('./public/locales')
}
path.resolve(...) instructs vercel to include this directory into your function's execution environment. @pablohpsilva, check if this works for you too.
@TKone7 That again sounds like the fault of whichever serverless platform you are using. You will need to ensure that your locale data remains in the filesystem.
I have this problem in OsX.
@TKone7 That again sounds like the fault of whichever serverless platform you are using. You will need to ensure that your locale data remains in the filesystem.
I have this problem in OsX.
Most helpful comment
Thanks for that hint, @isaachinman.
Found this article that presents a solution that works for the Vercel platform. Just adapt the file
next-i18next.config.jsas follows:path.resolve(...)instructs vercel to include this directory into your function's execution environment. @pablohpsilva, check if this works for you too.