How to display dynamic route segment on the same page
Answered
Polar bear posted this in #help-forum
Polar bearOP
I'm trying to display a dynamic segment of [id] of posts when I click on a single Link to a specific post, on the same page.
So Posts List and Selected Post will be on the same page
(Something like Outlets in react-router-dom)
But I don't really know how to.
I tried to use search params but it doesn't feel right.
page.tsx (/posts)
PostsList.tsx
Post.tsx
So Posts List and Selected Post will be on the same page
(Something like Outlets in react-router-dom)
But I don't really know how to.
I tried to use search params but it doesn't feel right.
page.tsx (/posts)
import Post from "@/components/Post";
import PostsList from "@/components/PostsList";
export default function PostsPage({
searchParams,
}: {
searchParams: { post?: string };
}) {
return (
<div className="flex">
<div className="flex-1">
<p>searching for Post: {searchParams.post}</p>
<PostsList />
<Post id={searchParams.post ?? ""} />
</div>
</div>
);
}PostsList.tsx
import { createClient } from "@/utils/supabase/server";
import Link from "next/link";
export default async function PostsList() {
const supabase = createClient();
const { data: posts } = await supabase.from("posts").select("id,title");
return (
<div>
<h1>Posts List</h1>
<ul>
{posts?.map((post) => (
<Link key={post.id} href={`/posts?post=${post.id}`}>
Post: {post.id}
</Link>
))}
</ul>
</div>
);
}Post.tsx
import { createClient } from "@/utils/supabase/server";
export default async function Post({ id }: { id: string }) {
const supabase = createClient();
const { data: post } = await supabase
.from("posts")
.select("*")
.eq("id", id)
.single();
return (
<div>
<h1>Post</h1>
<p>title: {post?.title}</p>
<p>id: {post?.id}</p>
<p>is_done: {post?.is_done ? "Yes" : "No"}</p>
</div>
);
}Answered by B33fb0n3
Yea, layouts can help there as well. You might also want to take a look at parallel routes (multiple page.tsx, but in the same route).
Is your initial issue solved?
Is your initial issue solved?
9 Replies
Polar bearOP
Now when I think about it Intercept routes should do that.
@Polar bear I'm trying to display a dynamic segment of [id] of posts when I click on a single Link to a specific post, on the same page.
So Posts List and Selected Post will be on the same page
(Something like Outlets in react-router-dom)
But I don't really know how to.
I tried to use search params but it doesn't feel right.
page.tsx (/posts)
tsx
import Post from "@/components/Post";
import PostsList from "@/components/PostsList";
export default function PostsPage({
searchParams,
}: {
searchParams: { post?: string };
}) {
return (
<div className="flex">
<div className="flex-1">
<p>searching for Post: {searchParams.post}</p>
<PostsList />
<Post id={searchParams.post ?? ""} />
</div>
</div>
);
}
PostsList.tsx
tsx
import { createClient } from "@/utils/supabase/server";
import Link from "next/link";
export default async function PostsList() {
const supabase = createClient();
const { data: posts } = await supabase.from("posts").select("id,title");
return (
<div>
<h1>Posts List</h1>
<ul>
{posts?.map((post) => (
<Link key={post.id} href={`/posts?post=${post.id}`}>
Post: {post.id}
</Link>
))}
</ul>
</div>
);
}
Post.tsx
tsx
import { createClient } from "@/utils/supabase/server";
export default async function Post({ id }: { id: string }) {
const supabase = createClient();
const { data: post } = await supabase
.from("posts")
.select("*")
.eq("id", id)
.single();
return (
<div>
<h1>Post</h1>
<p>title: {post?.title}</p>
<p>id: {post?.id}</p>
<p>is_done: {post?.is_done ? "Yes" : "No"}</p>
</div>
);
}
for dynamic routes you can access the parts of the dynamic routes within your page via the [params prop](https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes#example):
app/blog/[slug]/page.js => /blog/a => { slug: 'a' }
app/blog/[slug]/page.js => /blog/b => { slug: 'b' }
app/blog/[slug]/page.js => /blog/c => { slug: 'c' }
export default function Page({ params }: { params: { slug: string } }) {
return <div>My Post: {params.slug}</div>
}app/blog/[slug]/page.js => /blog/a => { slug: 'a' }
app/blog/[slug]/page.js => /blog/b => { slug: 'b' }
app/blog/[slug]/page.js => /blog/c => { slug: 'c' }
@Polar bear Now when I think about it Intercept routes should do that.
If you are not familiar with dynamic routes, you will have more difficulties than goodies when you implement them
@B33fb0n3 for dynamic routes you can access the parts of the dynamic routes within your page via the [params prop](https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes#example):
tsx
export default function Page({ params }: { params: { slug: string } }) {
return <div>My Post: {params.slug}</div>
}
app/blog/[slug]/page.js => /blog/a => { slug: 'a' }
app/blog/[slug]/page.js => /blog/b => { slug: 'b' }
app/blog/[slug]/page.js => /blog/c => { slug: 'c' }
Polar bearOP
This is a sketch of something I want to achieve on one page.
Dynamic routes have their own separate page.tsx
With react-router-dom I could just render that route on the same page in layout (using <Outlet/> )
I know that I can read params but that is on that specific page in [id] folder so I don't know if it helps here.
Dynamic routes have their own separate page.tsx
With react-router-dom I could just render that route on the same page in layout (using <Outlet/> )
I know that I can read params but that is on that specific page in [id] folder so I don't know if it helps here.
Polar bearOP
Okay I got it with layouts, seems like I lack basics understanding of well basics
Yea, layouts can help there as well. You might also want to take a look at parallel routes (multiple page.tsx, but in the same route).
Is your initial issue solved?
Is your initial issue solved?
Answer
Polar bearOP
Yep it is. Thank you so much!
Happy to help