It’s not feasible to create a new route file for every single blog post we want to publish! Instead we can use the $slug.tsx
filename convention with the dollar sign prefix to create a dynamic segment. Whatever you name the file is what the param will be called in your component.
Then there are a couple steps to take to get posts from your db based on the url param. First you’ll write a getPost
method in your post.server.ts
file that finds a unique post based on the slug. Then write a loader function that calls your getPost
method and returns JSON with your post.
Kent C. Dodds: [0:00] I think it's about time that these pages actually work. Let's make a dynamic route. We can't make a page that's one for every possible combination, like my-first-post.tsx, Onewheel, whatever. We're not going to make that.
[0:16] We need to have a dynamic parameter that can be passed to a single file that can then determine what to render based on that parameter. That parameter, we're going to call slug. We're going to use $slug.tsx. Whatever we call this name is what the parameter is going to be called.
[0:36] Let's export a default function called PostRoute(). Here, we'll return some JSX. We've got our post title. Let's make our post be title foo or whatever. That's the worst name ever, but that's what it's going to be. There, we've got foo in it. Whatever page we go to, anything goes. There it is. We have foo.
[1:02] We want to get this from the database, and that's going to happen on our backend. We're going to export const loader, which is a LoaderFunction. That's going to come from the specific runtime of node. This is an async function.
[1:18] Our LoaderFunctions accept a couple of things, and one of those is params. We can get our slug from params. We'll just destructure it. That slug is the same as the name here. If we were to change this to postId, then this, instead of slug, would be postId, but we're going to keep it as slug.
[1:41] Now, we can go ahead and find our post. We'd have a post is await getPost with the slug. We are going to define this getPost inside of our server. Let's export a function that's async, that takes the slug, which is a string, and returns prisma.post.findUnique where the slug is equal to the slug that we're given.
[2:05] Now, we can get this from our post server. Our slug could be undefined, and that's why we're getting a red underline there. We'll take care of that later. We're going to import also JSON from our remix-run/node server. We'll return JSON with the post. Great.
[2:24] Now, our post can come destructured from useLoaderData. With that, we should be able to get the proper title. If we go to "My First Post!", there it is, "My First Post!" If we go with our Onewheel, there it is. Perfect.
[2:39] We're getting our proper data by creating this PostRoute in this $slug directory. That gives us a param, which we can use to look up posts in our database by their slug. Then, we return that post which our PostRoute gets via useLoaderData and then renders out the post.title.