Как определить и использовать язык страницы в nextJS (ReferenceError: окно не определено)

Я пытаюсь сделать сайт, который мог бы определить страну и установить язык.

Чтобы сделать это в ответ, я использую для вызова window.navigator.language. Весь файл:

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

файлы pt / en - это просто JSONS со всеми текстами.

Но окно не существует в nextJS

Появляется эта ошибка: ReferenceError: окно не определено

Мне нужно использовать из файла реакции. Потому что я просто импортирую и использую вот так: {Перевести.header.label_opts_clients}

Я буду импортировать и использовать это в файле XML (реагировать) и в файле JSON. нравиться:

export const headerOptions = [
  {
    title: "`${Translate.header.label_opts_home}`",
...

Как я могу это сделать? Я знаю, что существует useRouter(hook), поэтому, если вам нужно взять URL-адрес страницы, вы можете использовать его. У меня уже была эта проблема, и я решил это:

...

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 = [];

...

Но это просто работает в функциональном компоненте.

Я попытался поместить условие в функцию и вернуть перевод, а также использовать перевод со скобками ({Translate().header.something}), но это не сработало.

Я тоже пытался использовать это (но не работает):

if (window !== undefined) {
  // browser code
}

И я не могу использовать хуки или компоненты, которые делал/буду монтировать.

Мои изображения кода:

Организация моей папки

Переводы

Код перевода

Как я буду импортировать

EN JSON

Другой мой JSON, который мне нужен для перевода

пытаюсь сделать useEffect в моем _app (laoult)

Проверка окна в JS-скрипте и вывод JSON-файла для перевода архива

🤔 А знаете ли вы, что...
С помощью JavaScript можно валидировать данные на стороне клиента, что улучшает пользовательский опыт.


5 072
2

Ответы:

На объект окна можно ссылаться после рендеринга DOM. Обычно он используется в хуке useEffect следующим образом:

useEffect(() => {
    console.info(window) // window is not undefined here
}, [])

в вашем случае, насколько я понимаю, вы пытаетесь проверить язык и вернуть содержимое из файла pt и в дальнейшем использовать его в другом компоненте реакции в качестве параметров заголовка.

Вот что может сработать, Измените файл перевода на функцию -

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

Теперь используйте его в своем файле реакции в функции useEffect -

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
}

Или, если вы хотите получить данные заголовка JSON из отдельного файла, вы можете создать отдельный файл следующим образом:

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
}

а затем используйте его в своем основном компоненте, например,

import getHeaderData from 'YOUR_PATH_TO_GETHEADERDATA'

const SomeReactComponent = (props) => {
    useEffect(() => {
        let headerData = getHeaderData(window)
    }, [])
}

Я надеюсь, что это работает.


Решено

Я нашел. Если вы используете NextJS v10.0.0, вы можете использовать новую расширенную функцию.

Интернационализированная маршрутизация — i18n

https://nextjs.org/docs/advanced-features/i18n-routing

Прежде всего, вам нужно настроить файл next.config.js и добавить экспорт модуля i18n. Если у вас уже были какие-то другие плагины (как у меня), вам нужно будет собрать их вместе.

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',
      },
});

С моим проектом, настроенным для языков, которые я хочу, я перешел к своему файлу перевода и использовал следующий хук - useRouter из 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 
}

И я просто использую в своем проекте как функцию:

{traducao().homeText.button_text}

Работает хорошо, распознает язык браузера и переключает. Но, к сожалению, вы не можете использовать в Json, потому что вы используете хук, а хуки просто работают в функциональном компоненте.