Can you create shallow links in app router?
Unanswered
Siamese Crocodile posted this in #help-forum
Siamese CrocodileOP
This code feels snappy because after clicking the link nextjs fetches RSC for route
/?login-=true even tho we already have this RSC because we are just changing search params. No data should change. In the pages router there was an option to pass shallow to <Link /> - Is there something like this in app router?// page.tsx
import Link from "next/link";
import { LoginDialog } from "./login-dialog";
import { Suspense } from "react";
import { cookies } from "next/headers";
export default function Home() {
cookies();
return (
<div className="h-screen w-screen place-items-center">
<Suspense>
<LoginDialog>
<Link
href={{
search: "?login=true",
}}
>
Login
</Link>
</LoginDialog>
</Suspense>
</div>
);
}
// login-dialog.tsx
"use client";
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
import { useRouter, useSearchParams } from "next/navigation";
export function LoginDialog({ children }: { children: React.ReactNode }) {
const searchParams = useSearchParams();
const router = useRouter();
const isOpen = searchParams.get("login") === "true";
const closeDialog = () => {
router.replace("/");
};
return (
<Dialog
open={isOpen}
onOpenChange={(open) => {
if (!open) {
closeDialog();
}
}}
>
<DialogTrigger asChild>{children}</DialogTrigger>
<DialogContent>Login</DialogContent>
</Dialog>
);
}45 Replies
so u triggering the modal because useSearchParams triggers and rerenders the component and that opens the modal cause login is true right
what u can do is using router.replace in your page.tsx (putting into clientside)
that will change the path on the clientside only without triggering anything on the server
Siamese CrocodileOP
It is a modal
do the thing i told u above
Siamese CrocodileOP
I know I can push it client side
But I dont get it why cant i push it using a link
cause link is a extended href with integrated next app router
the use of that is just to have navigation without using clientside code
the implementation u have is weird idk
Siamese CrocodileOP
"use client";
import { Button } from "@/components/ui/button";
import { useRouter } from "next/navigation";
export function LoginButton() {
const router = useRouter();
return <Button onClick={() => router.replace("?login=true")}>Login</Button>;
}triggering dialog using router push also downloads rsc
on click
so its also snappy
idk
Siamese CrocodileOP
"use client";
import { Button } from "@/components/ui/button";
export function LoginButton() {
function openLoginDialog() {
const params = new URLSearchParams();
params.set("login", "true");
window.history.pushState(null, "", `?${params.toString()}`);
}
return <Button onClick={openLoginDialog}>Login</Button>;
}This works
Looks stupid
why cant router have
shallow option@Siamese Crocodile why cant router have `shallow` option
i think the actual practical need for that is not big
in your case i would implement the modal logic on clientside and completely remove this searchparam thing
i cant really see the a reason why u would do this
Siamese CrocodileOP
Because i want to open model from multiple places
Also send a link to a login modal
@Siamese Crocodile Because i want to open model from multiple places
the same modal? u could implement your modal into a custom hook and trigger it that way
useLoginModal something like this
Siamese CrocodileOP
The same modal
useAuthModal
Siamese CrocodileOP
And how would you open a model when user gets an invite link
There is no way other than params
Thats a really common practice
yeah for sharing ofcourse lol
never said otherwise
Siamese CrocodileOP
So if i have a modal listetning for params
Then its convinient to open IT also from other places the same way
Instead of mixing state and params
u can listen for param change in your hook
so everywhere where u want to allow your modal to be opened u just have useLoginModal
somewhere in a top lvl wrapper
Siamese CrocodileOP
Useless, mounting modal once is easier and then modal listen to params and this login button adds param
Ive solved it, thanks
@Siamese Crocodile Useless, mounting modal once is easier and then modal listen to params and this login button adds param
its not useless, a hook is literally designed for singleton usage of any clientside code