为/api/* 配置跨域#
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
async headers() {
return [
{
source: "/api/(.*)",
headers: [{ key: "Access-Control-Allow-Origin", value: "*" }],
},
];
},
};
module.exports = nextConfig;
Next.js SSR/SSG theme 逻辑#
如果只考虑 SSR,那么将 theme 数据直接存在 cookie 里是最简单的方案。这样在服务端渲染时,可以直接从 cookie 中获取 theme 数据,然后在服务端渲染时,将 theme 数据传递给组件即可。
但是在 SSG 情况下,theme 数据只能存在浏览器环境中,如 localStorage。然而在服务端 SSG 时,无法获取 theme 数据。
所以,只能在浏览器渲染完 html 前,将 theme 数据写入 html 中,用户看到页面第一眼就是正确的 theme。
Next-Themes 可以实现这样的效果:
layout.tsx
import { ThemeProvider } from "next-themes";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" suppressHydrationWarning>
<body className={inter.className}>
<ThemeProvider
attribute="data-theme"
themes={themes}
defaultTheme={themes[0]}
storageKey="theme"
>
{children}
</ThemeProvider>
</body>
</html>
);
}
查看源码后,next-themes 的方案也是在客户端 html 渲染之前执行一段更新 css theme 变量的 script
处理 Nav 逻辑(怎么处理 Nav 的 active 状态)#
问题难点主要是,在 Server 端 和 Client 端,获取的 pathname 是一样。
直接使用 next/navigation 中的 usePathname 可以解决这个问题。
Nav.tsx
"use client";
import { usePathname } from "next/navigation";
import Link from "next/link";
export function Links() {
const pathname = usePathname();
return (
<nav>
<ul>
<li>
<Link className={`link ${pathname === "/" ? "active" : ""}`} href="/">
Home
</Link>
</li>
<li>
<Link
className={`link ${pathname === "/about" ? "active" : ""}`}
href="/about"
>
About
</Link>
</li>
</ul>
</nav>
);
}