I am using the “app” router in NextJS and want to use Dynamic Routes in the context of dynamically creating pages for posts for a blog.
I am having problems figuring out how to pass an Object to the dynamically created page, e.g. a Post
object with the type {id: number, title: string, likes: number}
. As far as I can tell, it doesn’t seem possible.
At best, let’s say I have a route /posts/[id]
, e.g. /posts/1
then I’ll be able to capture the 1
inside the dynamically created page by defining the type:
interface PostPageProps {
params: {
id: string;
};
}
and using it like so:
export default async function PostPage({ params }: PostPageProps) {
// ...
// params.id is available to me.
}
However, it does not seem possible to capture an entire custom Object, e.g. a Post
object in the dynamically created page.
Directory structure
/app
- /components
- /posts
- /[id]
- page.tsx
- page.tsx
- favicon.ico
- globals.css
- layout.tsx
- page.tsx
./app/posts/page.tsx
"use client";
// ...
type Post = {
id: number;
title: string;
likes: number;
};
export default function Page() {
const [posts, setPosts] = useState<Post[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
async function fetchPosts() {
...
}
fetchPosts();
}, []);
if (loading) return <p>Loading...</p>;
if (error) return <p>{error}</p>;
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<h1 className="text-3xl font-bold underline">
{posts.map((post) => (
<li key={post.id}>
<Link href={`/posts/${post.id}`} className="block">
{post.title}
</Link>
</li>
))}
</h1>
</main>
);
}
./app/posts/[id]/page.tsx
type Post = {
id: number;
title: string;
likes: number;
};
interface PostPageProps {
params: {
id: string;
};
}
export default async function PostPage({ params }: PostPageProps) {
const { id } = params;
console.warn(params);
return (
<div>
<h1>{id}</h1>
</div>
);
}
One way of getting access to a specific page is to use the id given in PostPageProps
to filter out the specific post of interest after loading in the data (which exists in the form of a .json
file in /public
). However, this would mean that I would have to load in the entire json file and filter it for a specific post everytime I access a specific post page. This is not good from a performance perspective, hence why I am trying to load it all in at once in the “parent” page from which I can each post to the dynamically created page (route). This is the way to do it if you’re using the App router in NextJS, note that this replaces usage of getStaticProps
which is not relevant in my case.
If there is a better way to do this in, feel free to enlighten me.