Reputation: 149
I am trying to conditionally render an account button when a user is authenticated; render a login + sign-up button when the user is not authenticated as follows:
My DesktopBar.tsx
file
import { getUser } from "@/app/_actions/userActions.ts"
import { NavItem } from "@/components/NavItem"
export async function DesktopBar() {
const user = await getUser()
return (
<div className="hidden md:flex md:w-full md:justify-between md:p-6">
<div className="flex items-center">
<NavItem key="home" page="/" text="home" className="text-4xl" />
</div>
<div className="flex items-center">
{user ? (
<NavItem key="/account" page="/account" text="Account" />
) : (
<>
<NavItem key="/login" page="/login" text="Login" />
<NavItem key="/sign_up" page="/sign_up" text="Sign Up" />
</>
)}
</div>
</div>
)
}
My userActions.ts
file
export async function getUser() {
const { data: user } = await supabase
.from("users")
.select("name, is_admin")
.single()
return user
}
When running this code, everything works as expected when refreshing the page. When logged in, it displays Account in my navbar when I am authenticated before the JS loads as expected.
The problem arises when I try to use a custom search form component to navigate to a page that is generated via generateStaticParams().
My SearchForm.tsx
file
"use client"
import { useRouter } from "next/navigation"
export function SearchForm() {
const router = useRouter()
function onSubmit(data) {
router.push(`${data[0]}/${data[1]}/${data[2]}`)
}
return (
<form onSubmit={onSubmit}>
<Button type="submit">Search 🔍</Button>
</form>
)
}
This is a simple abstraction of the form, all you need to know is that it takes in three inputs from a select box, and then routes the user to that route via router.push()
.
The user is routed to this route: /[a]/[b]/[c]/page.tsx
import { FC } from "react"
export const revalidate = 20
interface pageProps {
params: { a: string; b: string; c: string }
}
const page: FC<pageProps> = async ({ params }) => {
const { a, b, c } = params
// some logic happens...
}
// generate a combination of pages statically
export function generateStaticParams() {
const combinations = []
for (const a of letter1) {
for (const b of letter2) {
for (const c of letter3) {
combinations.push({ a, b, c })
}
}
}
return combinations
}
export default page
When I comment out the generateStaticParams() method, everything seems to work. But I have lots of dynamic pages and still want to statically generate them at build time rather than navigating to them dynamically.
The error message I get is Dynamic Server usage: cookies
. But I don't expect the code from Desktopbar.tsx
to affect /[a]/[b]/[c]/page.tsx
.
Finally, here is my root layout.tsx
where I render the Desktop bar.
import "@/styles/globals.css"
import DesktopBar from "@/components/DesktopBar"
export default function RootLayout({ children }) {
return (
<html>
<body className>
<DesktopBar />
<main>{children}</main>
</body>
</html>
)
}
Upvotes: 3
Views: 346
Reputation: 624
It's a little hard to understand exactly how you're putting this all together, especially since it doesn't show where exactly you're using cookies, but I think @thorwebdev was on the right track if this is even solvable with this structure. Try doing the opposite of what @thorwebdev recommended and setting export const dynamic = 'force-static'
, in places you want to, you know, force to be static, but know that this will cause cookies
to break for its children. Using cookies will force things to be dynamic, and using generateStaticParams
will try to force things to be static. If those two are nested, they're going to butt (but?) heads.
Upvotes: 0
Reputation: 1152
Try exporting the following from any routes that use the cookies
function:
export const dynamic = "force-dynamic";
Upvotes: 0