Write. Transform. Publish.
Latin vertΕ β to transform
Verto is a docs-and-blog hybrid built on Next.js 15. You write MDX. Verto transforms it into a polished, fully static site with Mintlify-style sidebar navigation, magazine-layout blog posts, and a custom inline comments system that turns footnotes into floating popovers.
One codebase, two content types. Docs get collapsible sidebar sections. Blog posts get date sorting and tag filtering. Everything is pre-rendered at build time, ships zero client-side JS for syntax highlighting, and deploys to Vercel with a single command.
- π Docs + blog hybrid β sidebar navigation for docs, magazine layout for blog, one codebase β Learn more
- π¬ Inline comments β
[^c-N]footnotes become highlighted text with click-to-reveal popovers β Learn more - π§© 10+ block components β Callout, Toggle, BookmarkCard, Figure, TaskList, Table, and more β Learn more
- π¨ Shiki syntax highlighting β dual light/dark themes, rendered at build time, zero client JS β Learn more
- π Dark mode β CSS variables, no-flash script, persists preference β Learn more
- βοΈ MDX authoring β Markdown with JSX components, compiled server-side β Learn more
- β‘ Pre-rendered at build time β every page statically generated, ready for Vercel β Learn more
- π§ Navigation β collapsible sidebar groups, auto-generated table of contents, mobile menu β Learn more
- π± Responsive design β mobile-first layout with adaptive breakpoints for sidebar, content, and table of contents β Learn more
Content goes in, static HTML comes out. Here's the pipeline:
flowchart LR
subgraph Content["π Content"]
MDX[".mdx Files"]
FM["Frontmatter\nParser"]
end
subgraph Transform["π Transform"]
direction TB
RM["remark\nβ’ GFM\nβ’ Inline Comments"]
RH["rehype\nβ’ Slug\nβ’ Autolink Headings\nβ’ Shiki v3\nβ’ Inline Comments"]
RM --> RH
end
subgraph Output["β‘ Output"]
RSC["React Server\nComponents"]
HTML["Static HTML"]
end
MDX --> FM --> RM
RH --> RSC --> HTML
style Content fill:#e8f5e9,stroke:#4caf50,stroke-width:2px
style Transform fill:#e3f2fd,stroke:#2196f3,stroke-width:2px
style Output fill:#fff3e0,stroke:#ff9800,stroke-width:2px
style MDX fill:#f1f8e9,stroke:#66bb6a,stroke-width:1px
style FM fill:#f1f8e9,stroke:#66bb6a,stroke-width:1px
style RM fill:#e8eaf6,stroke:#5c6bc0,stroke-width:1px
style RH fill:#e8eaf6,stroke:#5c6bc0,stroke-width:1px
style RSC fill:#fff8e1,stroke:#ffa726,stroke-width:1px
style HTML fill:#fff8e1,stroke:#ffa726,stroke-width:1px
| Layer | Technology | Version | Purpose | |
|---|---|---|---|---|
| βοΈ | Framework | Next.js | 15 | App Router, static generation |
| βοΈ | UI | React | 19 | Server Components |
| π | Language | TypeScript | 5 | Type safety |
| π¨ | Styling | Tailwind CSS | 4 | CSS-first config, design tokens |
| βοΈ | Content | MDX via next-mdx-remote | 5 | Markdown + JSX components |
| π¨ | Syntax | Shiki | 3 | Dual-theme code highlighting |
| π | Plugins | remark-gfm, rehype-slug, rehype-autolink-headings | β | Markdown extensions |
| π οΈ | Custom Plugins | remark/rehype-inline-comments | β | Inline comment system |
- π¦ Node.js 18.17 or higher
# Clone the repository
git clone https://github.com/tsaiggo/verto.git
cd verto
# Install dependencies
npm install
# Start the dev server
npm run devSite runs at http://localhost:3000.
| Command | Description |
|---|---|
npm run dev |
Dev server with hot reload |
npm run build |
Static production build |
npm start |
Serve the production build |
npm run lint |
ESLint |
npm run build
npm startnpx vercelStatic generation by default. No config needed.
verto/
βββ app/ β Pages and layouts (App Router)
βββ components/ β Layout (Navbar, Sidebar, ToC) + MDX blocks + UI
βββ content/ β MDX files for docs and blog + navigation.json
βββ lib/ β MDX pipeline, Shiki config, remark/rehype plugins, types
Create content/docs/{group}/{slug}.mdx:
---
title: Page Title
description: For SEO.
order: 1
---
Your content here.Register the page in content/navigation.json. Each group becomes a collapsible sidebar section.
Create content/blog/{slug}.mdx:
---
title: Post Title
description: Summary.
date: "2026-03-06"
author: Name
tags: ["tag"]
---
Your content here.Filename = URL slug. Posts sort by date descending.
| Component | Description |
|---|---|
Callout |
Admonitions: info, warning, tip |
Toggle |
Collapsible content block |
BookmarkCard |
Link preview card with title + description |
Figure |
Image with caption |
DiagramPlaceholder |
Placeholder for diagrams |
TaskList |
Checkbox task lists |
Table |
Styled Markdown tables |
BlockquoteStyled |
Styled blockquotes |
CodeBlock |
Shiki-highlighted code with dual themes |
InlineCode |
Styled inline code spans |
The signature feature. Uses Markdown footnote syntax with a c- prefix:
This took real effort[^c-1] to get right.
[^c-1]: Three days of SSR debugging. Worth it.[^c-N]β highlighted text + popover in Verto[^N]β regular footnote (still works)- Degrades to standard footnotes on GitHub, no content lost either way
A custom remark plugin walks the AST, finds the c- prefixed footnotes, and transforms them into special nodes. A matching rehype plugin converts those into custom HTML elements. The MDX component map renders them as highlighted text with popover UI.
This project is licensed under the Apache License 2.0. See the LICENSE file for details.
Made with β€οΈ by tsaiggo