You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 14中Layout.js获取localStorage及页面权限校验问题

解决方案:Next.js 14 页面校验 localStorage 并重定向

你的核心问题在于:默认的 Layout 是服务器组件(SSR),无法访问浏览器端的 localStorage;但直接加 "use client" 又会影响 metadata 的使用(metadata 仅支持服务器组件)。下面提供两种可行的调整方案:

方案一:保留 metadata,拆分客户端校验逻辑

把校验逻辑抽成独立的客户端组件,让原 Layout 保持服务器组件身份以保留 metadata:

  1. 创建客户端校验组件 AuthCheck.js:
"use client";

import { useEffect } from "react";
import { useRouter } from "next/navigation";

export default function AuthCheck({ children }) {
  const router = useRouter();

  useEffect(() => {
    const apiKey = localStorage.getItem("api-key");
    if (!apiKey) {
      router.push("/");
    }
  }, [router]);

  return <>{children}</>;
}
  1. 修改原 Layout 组件,引入并使用 AuthCheck:
import * as React from "react";
import AuthCheck from "./AuthCheck";

export const metadata = {
  title: "My Profile",
};

export default function StarforceProfileLayout({ children }) {
  return <AuthCheck>{children}</AuthCheck>;
}

说明:原 Layout 仍为服务器组件,metadata 正常生效;校验逻辑在客户端执行,确保只有存在 api-key 的用户才能看到页面内容。

方案二:放弃 metadata,改为客户端组件直接处理

如果对 SEO 要求不高,可以把整个 Layout 改为客户端组件,直接在里面完成标题设置和校验:

"use client";

import { useEffect } from "react";
import { useRouter } from "next/navigation";

export default function StarforceProfileLayout({ children }) {
  const router = useRouter();

  useEffect(() => {
    // 客户端设置页面标题
    document.title = "My Profile";
    
    // 校验 localStorage 中的 api-key
    const apiKey = localStorage.getItem("api-key");
    if (!apiKey) {
      router.push("/");
    }
  }, [router]);

  return <>{children}</>;
}

说明:这种方式无需拆分组件,但页面标题是在客户端渲染后才设置的,搜索引擎爬虫可能无法抓取到正确标题,适合对 SEO 要求较低的场景。

关键注意点

  • 服务器组件(默认无 "use client")无法访问浏览器 API(如 localStorage、document),这类操作必须放在客户端组件中执行。
  • redirect() 是服务器组件专用的重定向方法,客户端组件中需使用 useRouter 的 push/replace 方法。

内容的提问来源于stack exchange,提问作者mmd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 12:32:53