## Render the blog index page Now that we can render individual posts, let's wrap this up with the main page that renders a list of posts. Add `getPosts()` to the bottom of `lib/posts.ts`. Here's the final version: ```ts import { extractYaml } from "@std/front-matter"; import { join } from "@std/path"; const POSTS_DIR = "./posts"; // This is what gets parsed from the post front matter interface FrontMatter { title: string; published_at: string; blurb: string; } // This is what gets used for rendering export interface Post { slug: string; title: string; publishedAt: Date | null; blurb: string; content: string; } export async function getPost(slug: string): Promise<Post> { const text = await Deno.readTextFile(join(POSTS_DIR, `${slug}.md`)); const { attrs, body } = extractYaml<FrontMatter>(text); const post = { slug, title: attrs.title, publishedAt: attrs.published_at ? new Date(attrs.published_at) : null, blurb: attrs.blurb, content: body, }; return post; } export async function getPosts(): Promise<Post[]> { const files = Deno.readDir(POSTS_DIR); const promises = []; for await (const file of files) { if (file.name.startsWith(".")) continue; const slug = file.name.replace(".md", ""); promises.push(getPost(slug)); } const posts = (await Promise.all(promises) as Post[]) .filter((post) => post.publishedAt instanceof Date); posts.sort((a, b) => b.publishedAt!.getTime() - a.publishedAt!.getTime()); return posts; } ``` Here's the finished version of `routes/index.ts`: ```ts import { Handlers, PageProps } from "$fresh/server.ts"; import { getPosts, Post } from "../lib/posts.ts"; export const handler: Handlers<Post[]> = { async GET(_req, ctx) { const posts = await getPosts(); return ctx.render(posts); }, }; export default function BlogIndexPage(props: PageProps<Post[]>) { const posts = props.data; return ( <main class="max-w-screen-md px-4 pt-16 mx-auto"> <h1 class="text-5xl font-bold">My Awesome Blog</h1> <div class="mt-8"> {posts.map((post) => <PostCard post={post}/>)} </div> </main> ); } function PostCard(props: { post: Post }) { const { post } = props; return ( <div class="py-6 border(t gray-200)"> <a class="sm:col-span-2" href={`/${post.slug}`}> <h3 class="text-xl text-gray-900 font-bold hover:underline "> {post.title}&nbsp; <time class="font-medium text-gray-600"> ({post.publishedAt!.toLocaleDateString("en-us", { year: "numeric", month: "long", day: "numeric", })}) </time> </h3> <div class="text-gray-900"> {post.blurb} </div> </a> </div> ); } ``` Now navigate to the home page: https://localhost:8000 Voila! It should look decent and you should be able to click through to the individual posts. Try removing the `publish_at` property in the front matter of one of the posts. The post should no longer be displayed in the list nor be accessible via its slug. Congratulations, you now have a basic working blog engine!