Next.js Discord

Discord Forum

How to display dynamic route segment on the same page

Answered
Polar bear posted this in #help-forum
Open in Discord
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)

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?
View full answer

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):
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.
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?
Answer
Polar bearOP
Yep it is. Thank you so much!
Happy to help