"use client";
import { usePathname } from "next/navigation";
import Image from "next/image";
import i18n from "../../app/i18n";
import styles from "./styles.module.css";
import BR from "../../assets/images/official-pics/flags/BR.svg";
import FR from "../../assets/images/official-pics/flags/FR.svg";
import GE from "../../assets/images/official-pics/flags/GE.svg";
import SP from "../../assets/images/official-pics/flags/SP.svg";
import US from "../../assets/images/official-pics/flags/US.svg";
import BRAdvLogo from "../../assets/images/official-pics/bradv/logobradv.png";
import Socials from "../Socials";
import { useTranslation } from "react-i18next";
import { useLocalStorage } from "../../Hooks/useLocalStorage";
export default function Navbar() {
const { t } = useTranslation();
const pathname = usePathname();
//code below to load last language used
useLocalStorage("i18nextLng", "pt");
const handleChangeLanguage = (value: string) => {
i18n.changeLanguage(value);
};
return (
<div className={styles.container}>
<div className={styles.content}>
<Image src={BRAdvLogo} alt="logo" width={64} height={64} />
<Socials />
<div className={styles.nav}>
<a className={pathname === "/" ? styles.active : ""} href="/">
{t("navbar.home")}
</a>
<a
className={pathname === "/quem-somos" ? styles.active : ""}
href="/quem-somos"
>
{t("navbar.about")}
</a>
<a
className={pathname === "/contato" ? styles.active : ""}
href="/contato"
>
{t("navbar.contact")}
</a>
<a className={pathname === "/blog" ? styles.active : ""} href="/blog">
{t("navbar.blog")}
</a>
</div>
<div className={styles.available__languages}>
<div>
<button onClick={() => handleChangeLanguage("pt")}>
<Image src={BR} alt="Brazil" />
</button>
<button onClick={() => handleChangeLanguage("en")}>
<Image src={US} alt="United States" />
</button>
<button onClick={() => handleChangeLanguage("fr")}>
<Image src={FR} alt="France" />
</button>
<button onClick={() => handleChangeLanguage("de")}>
<Image src={GE} alt="Germany" />
</button>
<button onClick={() => handleChangeLanguage("es")}>
<Image src={SP} alt="Spain" />
</button>
</div>
</div>
</div>
</div>
);
}
所以我有上面的代码,用于导航栏组件,它使用 i18next 更改语言。这是一个 NextJS 项目。这适用于开发模式,但是当我尝试构建它时,它说 localStorage is not Defined(甚至使用像上面的代码这样的钩子或直接调用
localStorage.getItem('i18nextLng')
)。
我知道 localStorage 是一个浏览器变量,服务器端渲染的页面无法访问它,但这个组件是客户端渲染的,所以我不知道为什么它不起作用。
似乎找不到解决办法!
错误原因有:
window
或 document
。window
仅存在于客户端。因此,在定义 localStorage
之前,可能无法访问 window
。解决方案1:
typeof window !== 'undefined'
if (typeof window !== 'undefined') {
const item = localStorage.getItem('key)
}
上面的代码等待客户端挂载,然后访问localStorage。如果没有引用
window
,则返回未定义。同样,我们需要在访问 localStorage 之前对其进行定义。
解决方案 2:
useEffect
useEffect(() => {
const item = localStorage.getItem('key')
}, [])
useEffect
钩子是在客户端渲染中执行的,因此在Next.js SSR时不会执行。 => localStorage定义后我们就可以安全地访问它了。
祝你好运!