Directories and I18N
Answered
Terrier Brasileiro posted this in #help-forum
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
Hello, I'm a rookie to nextJS, still learning how's everything working. I've ran into an issue.
I have a folder structure
I have a folder structure
src/app
where the layout.tsx
and page.tsx
is located. I added my custom _app.tsx
to the src/pages/_app.tsx
folder, but it seems that my components aren't working with I18N translations this way.![Image](https://cdn.discordapp.com/attachments/1149237399717691442/1149237399931588698/image.png)
Answered by not-milo.tsx
next-i18next looks a little outdated to me. A native approach is better in my opinion, and if you really need an external library to do this then I'd suggest using [next-intl](https://next-intl-docs.vercel.app/docs/getting-started)
38 Replies
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
I'm trying to use
useTranslation()
inside of components folder.![Image](https://cdn.discordapp.com/attachments/1149237399717691442/1149237849254797362/image.png)
Page loads, but I get an error
react-i18next:: You will need to pass in an i18next instance by using initReactI18next
.![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
i18n is not trivial to set up and it gets even harder if you use both the app and pages router. I suggest you migrate all your pages to use the app router and then try implementing i18n as shown in Next.js' official examples here: https://github.com/vercel/next.js/tree/canary/examples%2Fapp-dir-i18n-routing
Long term it will be very beneficial to your codebase
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
How's the hierarchy would look like doing so?
I cannot move my
_app.tsx
to the src/app
directory, because it will not work![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
You can't use
_app.tsx
directly inside the app router![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
Understood, but how do I wrap my
layout.tsx
like the _app.tsx
?import { appWithTranslation } from 'next-i18next';
import type { AppProps } from 'next/app';
import '@styles/globals.scss';
const MyApp = ({ Component, pageProps }: AppProps) => {
return <Component {...pageProps} />
}
export default appWithTranslation(MyApp);
const inter = Inter({ subsets: ['latin'] });
export const metadata: Metadata = {
title: 'Alsteo',
description: 'Generated by create next app',
}
export async function generateStaticParams() {
return i18n.locales.map((lng) => ({ lng }));
}
const RootLayout = ({ children, params }: { children: React.ReactNode, params: { lang: string } }) => {
return (
<html lang={params.lang}>
<body className={inter.className}>
<main>
<Navigation />
{children}
</main>
</body>
</html>
);
}
export default RootLayout;
![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
I'm not familiar with next-i18next but they have a blog post detailing how to use it inside the app directory here: https://locize.com/blog/next-13-app-dir-i18n/
The app router works quite a bit differently from the pages router so you might also give a thorough read to [Next.js' documentation](https://nextjs.org/docs/app) about it
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
I'm not receiving any params, but the function works, what could be an issue?
import '@styles/globals.scss';
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import Navigation from '@/components/navigation/Nav';
import { i18n } from '../../next-i18next.config';
const inter = Inter({ subsets: ['latin'] });
export const metadata: Metadata = {
title: 'Alsteo',
description: 'Generated by create next app',
}
export async function generateStaticParams() {
return i18n.locales.map((lng) => {
return { lng }
});
}
const RootLayout = ({ children, params }: { children: React.ReactNode, params: { lng: string } }) => {
console.log(params);
return (
<html lang={params.lng}>
<body className={inter.className}>
<main>
<Navigation />
{children}
</main>
</body>
</html>
);
}
export default RootLayout;
![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
That's strange, how does your folder structure look like right now?
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
![Image](https://cdn.discordapp.com/attachments/1149237399717691442/1149256235682627614/image.png)
![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
Ooh, the
generateStaticParams
function needs to be inside the dynamic route. Create a layout.tsx
file inside /[lng]
and export it from there.![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
Yeah, but I'm trying to render a page that's in
app/page.tsx
it's rendering, but that page doesn't receive any of the params
but when I open
app/[lng]/page.tsx
, it displays the params there![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
If you're internationalising pages by using dynamic routes then all of your pages need to be inside that directory. Including the home page.
You can't see those params outside a dynamic route
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
Do you mean that I should remove
app/page.tsx
?![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
Not remove it, but just place it inside
/[lng]
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
Do I create the layout.tsx for the
/[lng]
?![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
Take [this](https://github.com/milovangudelj/milovangudelj.com/tree/master/app) as an example. You'll see there's no
pages.tsx
file inside /app
. Everything that needs to be internationalised sits under /[lang]
Yes
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
Right now there's another issue.
Home page
After entering
After entering
Home page
/
is getting an error, that there's no page.After entering
http://localhost:3000/en
, I still get an error (no page).After entering
http://localhost:3000/hello
or anything, that's not the locale
, it loads the page.![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
This is likely due to a misconfiguration of your middleware
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
Is middleware neccessary?
https://locize.com/blog/next-13-app-dir-i18n/
Step 2.0, it has a cookie export, but in settings there's none.
Step 2.0, it has a cookie export, but in settings there's none.
But that's the part of middleware
![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
Is this a brand bew application/website you're building?
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
Yeah
![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
Cause if it is, it would be way easier for you to follow the official example and not use any external i18n libraries
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
next-i18next looks a little outdated to me. A native approach is better in my opinion, and if you really need an external library to do this then I'd suggest using [next-intl](https://next-intl-docs.vercel.app/docs/getting-started)
Answer
![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
![Avatar](https://cdn.discordapp.com/embed/avatars/3.png)
Terrier BrasileiroOP
Thank you, that helped me a lot
![Avatar](https://cdn.discordapp.com/avatars/548149742207631360/2b1e750ac12613e7f54964225371f39b.webp?size=256)
not-milo.tsx
I'm glad it did 😎