Building a Markdown Blog with React Router v7
Building a Markdown Blog with React Router v7
This post covers the technical details of how this blog was built.
The Stack
- React Router v7 - Full-stack React framework with SSR
- Tailwind CSS v4 - Utility-first styling
- marked - Markdown to HTML conversion
- gray-matter - Frontmatter parsing
Server-Side Data Loading
React Router v7 uses a loader function for server-side data fetching:
export async function loader({ params }: Route.LoaderArgs) {
const post = await getPostBySlug(params.slug);
if (!post) {
throw new Response("Not Found", { status: 404 });
}
return { post };
}
Why Server-Side Rendering?
- SEO - Search engines can index content
- Performance - Content is ready on first paint
- Accessibility - Works without JavaScript
File Structure
content/
posts/
hello-world.md
building-a-markdown-blog.md
app/
lib/
markdown.server.ts
routes/
blog.tsx
blog.$slug.tsx
The .server.ts suffix ensures the file only runs on the server.