While you technically can have server functions in your route files, it’s not always the best choice.
For code that you never ever want in your client, it’s a best practice to move them into separate files, and name with the .server
convention. For example: posts.server.ts
Kent C. Dodds: [0:00] I don't know about you, but I do not want to author my posts in the source file. I want to get it from the database, so let's iterate a little bit to that. I typically like making model files for different models in my database. I'm going to make a post.server.ts and this is for accessing the post from the database.
[0:19] This is only going to be used on the server. We're using the .server convention to communicate to developers, as well as the Remix compiler, that the code in this file should never ever appear in the client bundle. The Remix compiler ensures that is the case.
[0:37] I'm going to export an async function called get_posts(). From here, I'm going to grab my posts and stick them right there. We'll return posts(), and then we'll get our posts from await get_posts(). If we double-check here, everything is still working as it was before, except now, our code is a little bit more organized, and it's ready for us to start interacting with the database in this module.
Note that you can absolutely interact with the database directly in your loader within your route module. I just find that it's typically better from a code organization standpoint to put all database interactions in a separate module.