PPR vs Parallel Routes: Can they do the same thing?
Answered
Thrianta posted this in #help-forum
ThriantaOP
Can I render a dynamic navbar as a @navbar "page"/slot, and have a SSG blog page/slot, and end up with something similar to PPR? As in, the blog post page/slot will be cached, and the navbar page/slot will be rendered dynamically and streamed in?
Answered by Thrianta
Unfortunately, after a trivial test, it doesn't work like that.
With build output of:
// src/app/@nav/page.tsx
import { cookies } from "next/headers";
export default function Navbar() {
return (
<div className="bg-slate-100 text-black p-5 flex flex-row justify-between">
<span>my nav bar</span>
<span>{cookies().get("user")?.value ?? "no-user"}</span>
</div>
)
}
// src/app/page.tsx
export default function Home() {
return (
<div>
<h1>Home</h1>
</div>
);
}
// src/app/layout.tsx
export default function RootLayout({
children,
nav
}: Readonly<{
children: React.ReactNode;
nav: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>{nav}{children}</body>
</html>
);
}With build output of:
bash
Route (app) Size First Load JS
┌ ƒ / 142 B 87.1 kB
└ ○ /_not-found 872 B 87.8 kB
+ First Load JS shared by all 87 kB
├ chunks/660-ce879c34dbe3fefb.js 31.5 kB
├ chunks/e6e143be-b81e610fa28b7c47.js 53.6 kB
└ other shared chunks (total) 1.86 kB
○ (Static) prerendered as static content
ƒ (Dynamic) server-rendered on demand15 Replies
This one question gives me a lot of headach, I hope PPR stable will soon be released so we can experiment more in practice and see how it works...
I'll try to sum it up though:
- PPR is a dynamic component in a static shell. Currently, if you want to keep a page static, but have request specific stuff to show in the interface, what you will do is crafting a client component. Client-side, you can send request to an API endpoint to get user specific data and display them. Ther rest of the page stays server-side, statically rendered. It sucks to have to use a client component. PPR is the same thing, but you can use dynamically server-side rendered component instead of a client component. Use case: a component showing the connected user's name, on a blog that is otherwise static
- PPR is a dynamic component in a static shell. Currently, if you want to keep a page static, but have request specific stuff to show in the interface, what you will do is crafting a client component. Client-side, you can send request to an API endpoint to get user specific data and display them. Ther rest of the page stays server-side, statically rendered. It sucks to have to use a client component. PPR is the same thing, but you can use dynamically server-side rendered component instead of a client component. Use case: a component showing the connected user's name, on a blog that is otherwise static
- parallel route is the most complicated pattern I've ever seen and is difficult to figure, but basically it's a kind of dynamic loading for RSCs. Say parallel routes do not exist, and you have 2 things to render : the main content of a blog post, and an administration area that allows admin to edit the content. You want the admin area only for admins of course.
what will you do ?
you will craft 2 components, import them, and render <Admin condtionnaly
like function BlogPage() { const isAdmin = checkAdminFromCookies(); return (<div><BlogPost />{isAdmin && <AdminArea /></div>)
I think the problem is that it means you are loading all the JS for AdminArea even if you don't render
with a parallel route, instead you let Next.js treat "AdminArea" as a route of its own, so it will split the code accordingly
if you don't render it, nothing happens
=> this needs verification though because I haven't used them much and didn't have time to run experiments around parallel routes
I don't know what happens eg if the page is static and one // route is dynamic
and not sure about how much PPR and // routes interact together, they don't exactly solve the same set of issues
they have more examples of // routes in the docs https://nextjs.org/docs/app/building-your-application/routing/parallel-routes#tab-groups
ThriantaOP
Thanks for your help, Eric. 🙂
I hope I can find the time to run a few experiments to test out // routes in depth. I also can't wait for PPR to become stable; I wish there was [areweturboyet](http://areweturboyet.com) for it!
Im going to leave this unanswered for now. Hopefully someone else contributes something juicy.
I hope I can find the time to run a few experiments to test out // routes in depth. I also can't wait for PPR to become stable; I wish there was [areweturboyet](http://areweturboyet.com) for it!
Im going to leave this unanswered for now. Hopefully someone else contributes something juicy.
ThriantaOP
Unfortunately, after a trivial test, it doesn't work like that.
With build output of:
// src/app/@nav/page.tsx
import { cookies } from "next/headers";
export default function Navbar() {
return (
<div className="bg-slate-100 text-black p-5 flex flex-row justify-between">
<span>my nav bar</span>
<span>{cookies().get("user")?.value ?? "no-user"}</span>
</div>
)
}
// src/app/page.tsx
export default function Home() {
return (
<div>
<h1>Home</h1>
</div>
);
}
// src/app/layout.tsx
export default function RootLayout({
children,
nav
}: Readonly<{
children: React.ReactNode;
nav: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>{nav}{children}</body>
</html>
);
}With build output of:
bash
Route (app) Size First Load JS
┌ ƒ / 142 B 87.1 kB
└ ○ /_not-found 872 B 87.8 kB
+ First Load JS shared by all 87 kB
├ chunks/660-ce879c34dbe3fefb.js 31.5 kB
├ chunks/e6e143be-b81e610fa28b7c47.js 53.6 kB
└ other shared chunks (total) 1.86 kB
○ (Static) prerendered as static content
ƒ (Dynamic) server-rendered on demandAnswer