All posts
2 min read

Hello, world: how this blog renders Markdown

A sample post that exercises every Markdown feature this blog supports, and a short tour of the pipeline that renders it.

Meta
Next.js
Markdown

This is a sample post. It exists to prove the rendering pipeline works, so it deliberately uses every Markdown feature the blog supports. Delete it once you have written a real one.

How posts work

Every post is a Markdown file in content/blog/. The filename becomes the URL slug, so this file lives at content/blog/hello-world.md and is served at /blog/hello-world.

Each file starts with a YAML frontmatter block:

---
title: 'Your post title'
description: 'One or two sentences, used for the listing page and social previews.'
date: '2026-07-25'
tags: ['Machine Learning', 'RAG']
---

title and date are required. The build fails loudly if either is missing, which beats silently publishing a post with no heading. description and tags are optional.

The pipeline

Four libraries, all open source, all running at build time:

LibraryRole
gray-matterParses the YAML frontmatter
react-markdownTurns Markdown into React elements
remark-gfmAdds GitHub-flavored extensions: tables, task lists, strikethrough
rehype-highlightSyntax highlighting via highlight.js

Nothing here ships to the browser. Posts are statically generated by generateStaticParams, so the parser and the highlighter run once during next build and visitors download plain HTML.

Code blocks

Fenced blocks are highlighted by language. Python:

def estimate_visibility(responses: list[str], entity: str) -> float:
    """Share of responses that mention the entity at least once."""
    hits = sum(1 for response in responses if entity.lower() in response.lower())
    return hits / len(responses)

TypeScript:

export type PostMeta = {
  slug: string
  title: string
  date: string
  tags: string[]
}

const sortByNewest = (posts: PostMeta[]) =>
  [...posts].sort((a, b) => b.date.localeCompare(a.date))

And a shell block:

npm run dev

Inline code such as getAllPosts() and content/blog/*.md is styled too.

Everything else

Regular text supports bold, italic, strikethrough, and links. External links open in a new tab; internal ones like the blog index use client-side navigation.

Blockquotes are styled as well. Useful for pulling out a result or a quote from a paper.

Ordered lists:

  1. First item
  2. Second item
  3. Third item

Unordered lists, with nesting:

  • Retrieval
    • Dense retrieval
    • Sparse retrieval
  • Generation
  • Evaluation

Task lists, from remark-gfm:

  • Set up the Markdown pipeline
  • Write a sample post
  • Write a real post

Horizontal rules work too:


Headings get automatic id attributes courtesy of rehype-slug, so you can link straight to the pipeline section.

A third-level heading

Nested headings render at sensible sizes, so long posts stay navigable.

Adding your next post

Create a new .md file in content/blog/, give it frontmatter, and it appears on the index automatically, sorted newest first. You do not need to update a registry or add an import anywhere.