Reputation: 435
Im trying to make a site that could identify the country and set the language.
To do this in react i use to call thw window.navigator.language. The entire file:
import * as pt from "./pt";
import * as en from './en';
let translate;
if (window.navigator.language == 'pt-PT' || window.navigator.language == 'pt-BR') {
translate = pt.default;
} else {
translate = en.default;
}
export default translate
the pt / en files its just JSONS with all texts.
But window doesnt exist in nextJS
That error appears: ReferenceError: window is not defined
I need to use out of a react file. Because i just import and use like this: {Translate.header.label_opts_clients}
I will import and I use this in a XML (react) file and in a JSON file like:
export const headerOptions = [
{
title: "`${Translate.header.label_opts_home}`",
...
How can i do this? I know that exist useRouter(hook), so if you need to take the url in a page you can use. I already had that problem, and i solved with this:
...
const { pathname } = useRouter()
const [crumbs, setCrumbs] = useState<string[]>();
useEffect(()=>{
renderCrumbs()
},[pathname])
const setHref = (links:string[], index:number|string) => {
let linkPath = ""
for (let i = 0; i <= index; i++) {
linkPath = linkPath + "/" + links[i]
}
return linkPath
}
const renderCrumbs = () => {
let links = pathname.split('/').slice(1);
let limit = links.length;
let array = [];
...
But this just work in a function component.
I tried to put the condition in a function and return the let translate, and use the translate with parentheses ({Translate().header.something}) but didnt work.
I tried to use this too (but doesnt work):
if (window !== undefined) {
// browser code
}
And i cant use hooks or components did/will mounth.
My code pictures:
My other JSON that i need to use the translate
trying to do a useEffect in my _app (laoult)
Window verification in JS script and brought the JSON file to translate archive
Upvotes: 0
Views: 7136
Reputation: 435
I found. If you are using NextJS v10.0.0 you can use a new advanced feature.
Internationalized Routing - i18n
https://nextjs.org/docs/advanced-features/i18n-routing
First of all you need to config your next.config.js and add the i18n module export. If you already had some other plugins (like me) you will need to put them together.
const withImages = require('next-images')
const path = require('path')
module.exports = withImages({
esModule: false,
i18n: {
locales: ['en-US', 'pt-BR', 'pt-PT', 'es-ES'],
defaultLocale: 'pt-BR',
},
});
With my project configured for the languages that i want, I went to my translation file and used a next hook - useRouter from next/router
import * as pt from "./pt";
import * as en from './en';
import { useRouter } from "next/router"
export const traducao = () =>{
let routes = useRouter();
let translate;
if (routes.locale == 'pt-PT' || routes.locale == 'pt-BR') {
translate = pt.default;
} else {
translate = en.default;
}
return translate
}
And the i just use in my project like a function:
{traducao().homeText.button_text}
Work well, recognizes the browser language and switche. But unfortunaly you cant use in a Json, because you are using a hook, and hooks just works in a function component.
Upvotes: 2
Reputation: 610
The window object can be referenced once the DOM is rendered. Usually, it is used in useEffect hook like so -
useEffect(() => {
console.log(window) // window is not undefined here
}, [])
in your case, from what I understand, you are trying to check the language and return the content from the pt file and further use it in another react component as header options.
Here's what might work, Change your translate file to a function -
import * as pt from './pt'
import * as en from './en'
const translate = (window) => {
const { language } = window.navigator
if(language == 'pt-PT' || language == 'pt-BR') return pt.default
else return en.default
}
export default translate
Now use it in your react file in a useEffect function -
import translate from 'YOUR_PATH_TO_TRANSLATE'
const SomeReactComponent = (props) => {
useEffect(() => {
const translatedData = translate(window) // now window is defined
let headerData = {
title: translatedData.header.label_opts_home
...
}
}, []) // componentDidMount in classes
}
Or, if you want to get the JSON header data from a separate file, you can create a separate file like so -
import translate from 'YOUR_PATH_TO_TRANSLATE'
const getHeaderData = (window) => {
const translatedData = translate(window) // now window is defined
let headerData = {
title: translatedData.header.label_opts_home
...
}
return headerData
}
and then, use it in your main component like so,
import getHeaderData from 'YOUR_PATH_TO_GETHEADERDATA'
const SomeReactComponent = (props) => {
useEffect(() => {
let headerData = getHeaderData(window)
}, [])
}
I hope this works.
Upvotes: 0