Next.js Discord

Discord Forum

Navigation with params and receiving them

Answered
Amur catfish posted this in #help-forum
Open in Discord
Amur catfishOP
Hello i'm trying to navigate from one page to another, and i'm intending to send a uid as a param in the url to then query the api once i'm in the layout of the other page.
My problem being i can't figure out how to access the url params i sent.
i tried doing it this way but i get undefined:

import { Suspense } from "react";
interface InscriptionLayoutProps {
    children: React.ReactNode;
    params: { uid: string }
}
export default async function InscriptionRootLayout({ children, params }: InscriptionLayoutProps) {
    const navigationData = navBarData as NavBarProps;
    console.log(params.uid)
    return (
        <div className="bg-none md:bg-gradient-card relative ">
            <Suspense fallback={<div>Loading....</div>}>
                <HeaderTop
                    profession={navigationData.profession}
                    display='flex lg:hidden  w-auto sticky top-0 z-50 h-[10lvh]'
                />
            </Suspense>
            {children}


        </div>
    );
}
Answered by joulev
Suspense must wrap the component calling the hook. So
// ❌ this does not work
function Component() {
  const sp = useSearchParams();
  return (
    <Suspense fallback={...}>
      ...
    </Suspense>
  );
}

// ✅ this works
function Component() {
  const sp = useSearchParams();
  return ...
}
function SuspensedComponent() {
  return (
    <Suspense fallback={...}>
      <Component />
    </Suspense>
  );
}
View full answer

83 Replies

Amur catfishOP
do i need the UID as a dynamic page?
i'm trying to send a uid in the URL to then make api calls in the page to recover the data of some sessions from my API
i'm not sure how you sent the url param. is it a normal param or a search query param (?uid=foo)?
Amur catfishOP
useEffect(() => {
        console.log(selectedSession);
        setSingupUrl(`/signup?uid=${encodeURIComponent(selectedSession.id)}`);
    }, [selectedSession]); (it gets formed depending of the choice of a dropbox)
<Link href={singupUrl} passHref>
as a search query param, it's the product of choosing a date in a dropbox then clicking to go to the sigunp page w the information of the thing chosen
Something like this
so layout (server component) doesn't receive searchparams: https://nextjs.org/docs/app/api-reference/file-conventions/layout#layouts-do-not-receive-searchparams.

you need to use a client component to read the search query param using useSearchParams
only page.tsx files receive search params in the server component level.
Amur catfishOP
logic wise if i'm doing all API calls server side how could i archieve this?
there's no way? my component must be client side? in that case does that means i need to do useEffect for my API call?
say i'm gonna use the uid to do a api query to api/sessions/{uid}
any reason why this must be in a layout? what should happen when you go from /foo?uid=1 to /bar?uid=2 with both pages under the same layout?
Amur catfishOP
well i was told to do everything server side, following the logic i read the layout comes first
so under that logic i do the api call first on the layout to then having pre-fetched everything for said page
yeah but depending on the answer to the question of /foo?uid=1 to /bar?uid=2 above, i probably have different suggestions for you on how to achieve this
nothing requires that this must be in a layout
it just has to be a page
Amur catfishOP
okay!
@joulev nothing requires that this must be in a layout
Amur catfishOP
I'm new to Next yet, so i just figured it'd be done in the layout as next doc says u can server side fetch from the layout
if you are in a page then it's pretty simple
export default function Page({ searchParams }) {
  console.log(searchParams.uid);
  return <div>Hello world</div>;
}
@Amur catfish I'm new to Next yet, so i just figured it'd be done in the layout as next doc says u can server side fetch from the layout
you can server side fetch from the page as well. typically you would fetch in the layout for things that are shared by many pages. in this case the uid is specific to the page so you would want to do it inside the page itself
Amur catfishOP
what's the type of searchParams? how would the inferface be?
Interface MyParams{
searchParams : ReactNode?
}
type SearchParams = Record<string, string | string[] | undefined>
string when ?uid=1
string[] when ?uid=1&uid=2
undefined when uid is not specified
@joulev you can server side fetch from the page as well. typically you would fetch in the layout for things that are shared by many pages. in this case the uid is specific to the page so you would want to do it inside the page itself
Amur catfishOP
it kinda is shared by all pages under (inscription) :
maybe my logic is wrong but basically is a formulary that has pre-loaded data in function of the session data that was chosen
everything insidfe signup uses the information of the query done via the uid
@Amur catfish it kinda is shared by all pages under (inscription) :
uhm. what should happen when you go from /signup?uid=1 to /signup/assisted?uid=2? (users can always navigate arbitrarily like this btw)
Amur catfishOP
They'd go from --"formideo m'inscrit"-->to this formulary with prefetched information that came from the choosing of the dropbox (styles not yet finished)
i ask because when you reach /signup/assisted?uid=2, do you want to keep the data you got from uid=1, or do you want to fetch fresh data for uid=2?
Amur catfishOP
i'd wish to keep it
in principle i only need it on the assisted one.
@Amur catfish i'd wish to keep it
in that case users will see uid=2 but still have data from uid=1, which is mismatched. this type of mismatches is the reason why you can't read search params in layouts, and you must work around it if you are willing to get this mismatch.

it's important i'll stress this again. this is a logical mismatch, will be buggy, and hence not recommended.

if you understand the risk, then you follow the steps here https://stackoverflow.com/a/75363135. then you will have the full URL in the layout which you can then parse and extract the search query param.
Amur catfishOP
in the assisted i use the information but i kinda need to pass the searchParam across 2 pages from
/a?uid=123fc
to
signup?uid="sdfs"
to
signup/assisted?uid="fdsdsfds"
sounds to me you should just replicate the search param handling mechanism across all page files there
@Amur catfish i mean it's not forced to be layout i just thought it was the best idea, the only true page that uses it it's the /assisted one
no it's absolutely not the best idea. it's perhaps the worst idea you can think of in this case.
search params don't go along with layouts and that's by design.
Amur catfishOP
so all data fetching in layout
is for getAlls()
and specifics in page?
to put it in words
@joulev if you are in a page then it's pretty simple tsx export default function Page({ searchParams }) { console.log(searchParams.uid); return <div>Hello world</div>; }
since you only need the uid in the assisted page why not just do the handling there? just do this in that assisted page
why bother with layouts when other signup pages dont need it?
Amur catfishOP
because i needed to pass it somehow to the assisted one
by passing via sigunp
and i dind';t know how
how do you navigate from signup to signup assisted?
@joulev since you only need the uid in the assisted page why not just do the handling there? just do this in that assisted page
Amur catfishOP
I'll try this tomorrow (it's 18h end of work day )
@joulev how do you navigate from signup to signup assisted?
Amur catfishOP
A button w a link in another page
because we choose a date:
then this button sends to the signup page:
and in the signup page on decide if "assisted or self"
we can't just jump to assisted, or well we can but that'd mean change design and such
@Amur catfish A button w a link in another page
"use client";
import Link from "next/link";
import { Suspense } from "react";

function NextPageLink() {
  const sp = useSearchParams();
  const uid = sp.get("uid");
  return (
    <Link href={`/signup/assisted?uid=${uid}`}>
      Next
    </Link>
  );
}
Amur catfishOP
i need to useSearchParams to do my API call in the page, that means i can't use client as it's server side
@joulev tsx "use client"; import Link from "next/link"; import { Suspense } from "react"; function NextPageLink() { const sp = useSearchParams(); const uid = sp.get("uid"); return ( <Link href={`/signup/assisted?uid=${uid}`}> Next </Link> ); }
Amur catfishOP
The link im forming it without problems and getting into the page, it's from the page that i need to access the search params but server side
i got asked to not do client for data fetch
Then sorry, I still don’t understand what you are trying to make so can’t offer any advice
@joulev Then sorry, I still don’t understand what you are trying to make so can’t offer any advice
Amur catfishOP
I'm trying to do an API call based on parameters i had on the URL at request time
i'd wish to know how to do this on server side and not use client or use effect to do api calls
not necesary in the layout, in the page is fine
i managed to get the search param in the corresponding page doing what you proposed but
how can i do my fetch call without useEffect is it possible?
if my component became client
when using search params
const SelfSignupBody = (

) => {
    const sp = useSearchParams();
    const uid = sp.get('uid');
    console.log(uid);
    return (
        <InscriptionBody
            containerStyle="h-full"
            bodyBackground={<Image
                src={'/images/meufInscriptionSeul.png'}
                alt="meuf qui s'inscrit seule"
                width={720}
                height={980}
                className="h-fit lg:h-auto"
            />} >
            <div className="h-fit flex flex-col gap-y-5 py-5">
                <Suspense fallback={<div>Chargement...</div>}>
                    <Link href={`/signup?${uid}`}>
                        <CloseXIcon width={20} height={20} className="absolute top-5 right-5 cursor-pointer" />
                    </Link>
                </Suspense>...
i wrapped the part in Suspense
what am i missing or not understanding?
@Amur catfish i wrapped the part in Suspense
Suspense must wrap the component calling the hook. So
// ❌ this does not work
function Component() {
  const sp = useSearchParams();
  return (
    <Suspense fallback={...}>
      ...
    </Suspense>
  );
}

// ✅ this works
function Component() {
  const sp = useSearchParams();
  return ...
}
function SuspensedComponent() {
  return (
    <Suspense fallback={...}>
      <Component />
    </Suspense>
  );
}
Answer