使用 clerk.js 时,访问主路由 (/) 会导致 next.js 14 中的整页刷新

问题描述 投票:0回答:1

我正在使用

@clerk/nextjs": "^4.29.5"
作为我的
next.js 14
应用程序的身份验证系统。我正在使用 context-api 管理一些全局状态。我的问题是,当我重新访问我的主路线 (/) 时,页面完全重新加载,而不是软导航(其他路线都可以)。这仅发生在托管的
(vercel)
应用程序中,而不是在本地主机中,甚至当我使用
npm start
运行构建版本时。如何解决这个问题?我在这里做错了什么?我不想重新加载整个页面。

项目结构:

app/
  (auth)
    layout.tsx
    sign-in/
    sign-up/
  (root)
    layout.tsx
    page.tsx
  layout.tsx

布局.ts:

import { MainContextProvider } from "@/contexts/MainContext";
import ClerkThemeProvider from "@/lib/providers/ClerkThemeProvider";
import { Suspense } from "react";
import MainPageFallback from "@/components/shared/MainPageFallback";
import { Toaster } from "@/components/ui/toaster";


export default function RootLayout({ children }: { children: React.ReactNode }) {
    return (
        <html lang="en">
            <body className={`${inter.className}`}>
                <MainContextProvider>
                    <Suspense fallback={<MainPageFallback />}>
                        <ClerkThemeProvider>{children}</ClerkThemeProvider>
                    </Suspense>
                </MainContextProvider>
                <Toaster />
            </body>
        </html>
    );
}

/contexts/MainContext.ts:


"use client";

import { createContext, useEffect, useState } from "react";

export const MainContext = createContext({
    lang: "",
    theme: "",
    sidebarOpen: false,
    handleLang: () => {},
    changeTheme: () => {},
    closeSidebar: () => {},
    openSidebar: () => {},
});

export const MainContextProvider = ({ children }: { children: React.ReactNode }) => {
    const [lang, setLang] = useState("en");
    const [theme, setTheme] = useState("light");
    const [sidebarOpen, setSidebarOpen] = useState(false);

    useEffect(() => {
        const savedTheme = localStorage.getItem("theme");
        const savedLang = localStorage.getItem("lang");

        setLang(savedLang ? savedLang : "en");
        setTheme(savedTheme ? savedTheme : "light");
    }, []);

    useEffect(() => {
        localStorage.setItem("lang", lang);
        document.documentElement.lang = lang;
    }, [lang]);

    useEffect(() => {
        localStorage.setItem("theme", theme);
        if (theme === "dark") {
            document.body.classList.add("dark");
        } else {
            document.body.classList.remove("dark");
        }
    }, [theme]);

    const handleLang = () => {
        setLang(lang === "en" ? "bn" : "en");
    };

    const changeTheme = () => {
        setTheme(theme === "light" ? "dark" : "light");
    };

    const openSidebar = () => {
        setSidebarOpen(true);
    };

    const closeSidebar = () => {
        setSidebarOpen(false);
    };

    return (
        <MainContext.Provider
            value={{
                lang,
                theme,
                sidebarOpen,
                handleLang,
                openSidebar,
                changeTheme,
                closeSidebar,
            }}
        >
            {children}
        </MainContext.Provider>
    );
};

/lib/providers/ClerkThemeProvider.tsx


"use client";

import { MainContext } from "@/contexts/MainContext";
import { ClerkProvider } from "@clerk/nextjs";
import { dark } from "@clerk/themes";
import { useContext } from "react";

export default function ClerkThemeProvider({ children }: { children: React.ReactNode }) {
    const { theme } = useContext(MainContext);

    return (
        <ClerkProvider appearance={{ baseTheme: theme === "dark" ? dark : undefined }}>
            {children}
        </ClerkProvider>
    );
}

中间件.ts


import { authMiddleware } from "@clerk/nextjs";

export default authMiddleware({
    // An array of public routes that don't require authentication.
    publicRoutes: ["/", "/about", "/contact", "/api/webhooks(.*)", "/api/uploadthing"],

    // An array of routes to be ignored by the authentication middleware.
    ignoredRoutes: ["/api/webhooks(.*)"],
});

export const config = {
    matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
};

authentication next.js14 clerk
1个回答
0
投票

我解决了这个问题。我想分享它。这是一个简单的原因,为什么主路由总是在部署的版本上完全重新加载。这不是

clerk
软件包原因。

我只需在

loading.tsx
文件夹中添加一个
app/
文件,然后就不会再发生完全重新加载。

© www.soinside.com 2019 - 2024. All rights reserved.