Build a Tiny Docs Site with Next.js in Under an Hour

A full-blown documentation platform (Docusaurus, Mintlify, etc.) is great when you’re at scale, but sometimes you just need something tiny. Let’s build a minimal docs site using Next.js + Markdown.

We will:

Scaffold a Next.js app

Add a tiny “docs engine” with a docs list

Render docs pages from Markdown

Create a Next.js App

From your project folder:

npx create-next-app@latest simple-docs-site
cd simple-docs-site

You can accept the defaults. We’ll assume the App Router (app/ directory) is enabled, which is the default in newer Next.js versions.

Add Some Docs Data

We’ll keep this simple: a tiny “database” as a TypeScript file with Markdown strings.

// lib/docs.ts
export type Doc = {
slug: string;
title: string;
content: string; // markdown
};

export const docs: Doc[] = [
{
slug: "getting-started",
title: "Getting Started",
content: `
# Getting Started

Welcome to our docs site! 🎉

This is a simple markdown-powered page.

## What you can do

- Learn the basics
- Click around
- Extend it later with a real CMS

\`\`\`bash
npm install
npm run dev
\`\`\`
`,
},
{
slug: "api-reference",
title: "API Reference",
content: `
# API Reference

Here's a fake API:

\`\`\`http
GET /api/users
\`\`\`

Returns a list of users.
`,
},
];

export function getAllDocs() {
return docs;
}

export function getDocBySlug(slug: string) {
return docs.find((doc) => doc.slug === slug);
}

This gives us:

A list of docs (docs)

A helper to get them all

A helper to get a single doc by slug

Later, you can swap this with a real CMS (Ghost, Contentful, etc.) without changing your pages much.

Install a Markdown Renderer

npm install marked

This converts Markdown into HTML inside your Next.js pages.

Create the Docs List Page

Replace your app/page.tsx with the following:

import Link from "next/link";
import { getAllDocs } from "@/lib/docs";

export default function HomePage() {
const allDocs = getAllDocs();

return (

Simple Docs


A tiny docs site powered by Next.js and Markdown.



{allDocs.map((doc) => (

<Link
href={`/docs/${doc.slug}`}
className="text-blue-600 hover:underline"
>
{doc.title}


))}


);
}

This displays a list of your docs with links.

Create the Dynamic Docs Page

Create app/docs/[slug]/page.tsx:

import { notFound } from "next/navigation";
import { marked } from "marked";
import { getAllDocs, getDocBySlug } from "@/lib/docs";

type DocPageProps = {
params: { slug: string };
};

export default function DocPage({ params }: DocPageProps) {
const doc = getDocBySlug(params.slug);

if (!doc) {
return notFound();
}

const html = marked.parse(doc.content);

return (


← Back to docs


{doc.title}

<article
className="prose prose-sm sm:prose lg:prose-lg"
dangerouslySetInnerHTML={{ __html: html }}
/>

);
}

export async function generateStaticParams() {
const docs = getAllDocs();
return docs.map((doc) => ({ slug: doc.slug }));
}

This:

Looks up the doc by slug

Converts Markdown → HTML

Renders it in the page

Run the Project

npm run dev

Visit:

/ → Docs list

/docs/getting-started → Individual doc page

Next Steps

You can extend this simple docs site by:

Moving docs into real .md files

Pulling content from Ghost using its Content API

Adding a sidebar or search

Deploying instantly on Vercel