Having a bit of trouble with Next.js Static Site Generation (SSG) and protected routes. SSG requires data to be available at build time, while protected routes need user authentication which isn't possible during this phase. The pages I'm trying to load require heavy database calls that result in static information updated once a day through a revalidation process at night.
Is there a way to bypass the Authentication phase during the building process so that "npm run build" still generates pre-rendered pages correctly while keeping them protected in production?
The typical implementation for Clerk involves addressing the Layout layer first:
import { ClerkProvider, SignInButton, SignedIn, SignedOut, UserButton } from '@clerk/nextjs';
import './globals.css';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider>
<html lang="en">
<body>
<header>
<SignedOut>
<SignInButton />
</SignedOut>
<SignedIn>
<UserButton />
</SignedIn>
</header>
<main>{children}</main>
</body>
</html>
</ClerkProvider>
)
}
However, if one of my pages involves heavy server-side actions like retrieving employee data from the database:
import { getAllEmployeesFromDatabase } from "@/lib/serverEmployeeLib";
import { EmployeeDataTable } from "@/components/EmployeeDataTable";
import React from "react";
async function EmployeesPage() {
const employeeData = await getAllEmployeesFromDatabase();
return (
<div>
<EmployeeDataTable
data={employeeData}
/>
</div>
);
}
export default EmployeesPage;
The getAllEmployeesFromDatabase()
won't be called during build time if it's part of a protected route.
I've considered an alternative approach but it seems cumbersome and counterintuitive as it goes against the idea of having a centralized protected layout. It would entail adding extra authentication logic to individual pages:
import { getAllEmployeesFromDatabase } from "@/lib/serverEmployeeLib";
import { EmployeeDataTable } from "@/components/EmployeeDataTable";
import React from "react";
async function EmployeesPage() {
const employeeData = await getAllEmployeesFromDatabase();
return (
<ClerkProvider>
<SignedOut>
<SignInButton />
</SignedOut>
<SignedIn>
<UserButton />
</SignedIn>
<div>
<EmployeeDataTable data={employeeData} />
</div>
</ClerkProvider>
);
}
export default EmployeesPage;
Any thoughts on a proper way to handle this? Thanks!