Navigation with params and receiving them
Answered
Amur catfish posted this in #help-forum
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:
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>
);
}83 Replies
@Amur catfish 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:
tsx
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>
);
}
app/.../
[uid]/
layout.tsxlayout.tsx can receive the uid here.
app/.../
layout.tsx
[uid]/page.tsxlayout.tsx cannot receive the uid here.
what are you trying to achieve?
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
you need to use a client component to read the search query param using
useSearchParamsonly 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@Amur catfish well i was told to do everything server side, following the logic i read the layout comes first
you can just do it in the page
nothing requires that this must be in a layout
@joulev 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
i go from something like :
http://localhost:3000/formation/cancers-du-sein-non-metastatiques
to
localhost:3000/signup?uid=fjRjn
something like that
http://localhost:3000/formation/cancers-du-sein-non-metastatiques
to
localhost:3000/signup?uid=fjRjn
something like that
@Amur catfish i go from something like :
http://localhost:3000/formation/cancers-du-sein-non-metastatiques
to
localhost:3000/signup?uid=fjRjn
something like that
yes and get the uid inside
signup/page.tsxit 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?
}
Interface MyParams{
searchParams : ReactNode?
}
type SearchParams = Record<string, string | string[] | undefined>string when ?uid=1string[] when ?uid=1&uid=2undefined 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
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.
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" tosignup/assisted?uid="fdsdsfds"sounds to me you should just replicate the search param handling mechanism across all page files there
@joulev 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
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
@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
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:
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 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.
But follow this if you want to force-get the search params in the layout, despite being aware it may produce a logical mismatch and bugs.
@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
@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
i tried doing this but i think i do it wrong ro something because i can't access the search param
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
it builds
and i access the search params properly