Accessing search Params from Sever Side Layout File in Next.JS 13 (App Router)

1k views Asked by At

I need to access searchParams named promo on layout file which is server side rendered? Is it really impossible to access search params in server side rendered layout file?

layout.tsx

import React from "react"
import { redirect } from "next/navigation"
import { currentUser } from "@clerk/nextjs"
import { getUser } from "@/lib/actions/user.actions"

const DashBoardLayout = async ({ children, searchParams }: { children: React.ReactNode, searchParams: { promo: string } }) => {

  // searchParams is Undefined, but works on other server components (page.tsx), but not on layout.tsx
  console.log(searchParams)

  const user = await currentUser()
  if (!user) redirect(`/sign-in?promo=${searchParams?.promo}`)
  const userInfo = await getUser(user.id)
  if (!userInfo) redirect(`/onboarding?promo=${searchParams?.promo}`)


  return <>{children}</>
}

export default DashBoardLayout

works on normal page.tsx

import { redirect } from "next/navigation"
import { getCourses } from "@/lib/actions/course.actions"

const page = async ({searchParams}: {searchParams: {promo: string}}) => {
  const courses = await getCourses()
  if (!courses || !courses.length) {
    redirect("/create-course")
  }
  const courseId = courses[0].id
  console.log(searchParams.promo)
  redirect(`/purchase/${courseId}?promo=${searchParams.promo}`)
  return <div>page</div>
}

export default page

I have checked this post, but it didn't mention for server components, especially for layout files, It would only work for page.tsx files.

Question states it's impossible, I need some alernative to access SearchParams in server-side rendered layout.tsx

1

There are 1 answers

2
Jung hyeonuk On

SearchParams is not accessible on layout layer.

https://nextjs.org/docs/app/api-reference/file-conventions/page#params-optional

searchParams is a Dynamic API whose values cannot be known ahead of time. Using it will opt the page into dynamic rendering at request time.

 if (!user) redirect(`/sign-in?promo=${searchParams?.promo}`)
  const userInfo = await getUser(user.id)
  if (!userInfo) redirect(`/onboarding?promo=${searchParams?.promo}`)

Anyway, Is there any reasons you're doing this especially on layout?

If you just want to redirect users before page rendering, I'd rather redirect users with middleware because functions on middleware are executed before rendering.