A Next.js tool that converts standard markdown files into rendered blog posts for @san-siva/blogkit.
Note: This blog post is translated from the README.md file in the blogkit-md repository.
git clone https://github.com/san-siva/blogkit-md.git
npm installnpm run dev # uses data/test.md by default
npm run dev -- --file=data/my-post.md # specify a markdown fileThe dev server watches the markdown file for changes and auto-reloads the browser via HMR.
npm run build
npm run startnpm run lint # check
npm run fix # auto-fixblogkit-md exposes a BlogPost server component you can drop into any Next.js project.
npm install @san-siva/blogkit-mdOr as a local package:
"@san-siva/blogkit-md": "file:../blogkit-md"Add it to transpilePackages in your next.config.ts:
const nextConfig = {
transpilePackages: ['@san-siva/blogkit-md'],
};import { BlogPost } from '@san-siva/blogkit-md';
export default function Page() {
return (
<BlogPost
filePath="content/my-post.md"
jsonLd={{
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: 'My Post',
description: 'Post description',
datePublished: '2026-01-01',
author: { '@type': 'Person', name: 'Your Name' },
}}
/>
);
}filePath
string
Yes
Path to the markdown file. Relative paths are resolved from process.cwd().
jsonLd
WithContext<Thing>
No
Optional JSON-LD schema passed to <Blog> for structured data / SEO.
Headings
# H1 ## H2 ### H3 #### H4
Paragraph
Plain text
Hard line break
Two spaces at end of line
Bold
**bold**
Italic
_italic_
Inline code
`code`
Link
[text](url)
Image

Ordered list
1. item
Unordered list
- item
Table
GFM table syntax
Code block
```lang
Mermaid diagram
```mermaid
Thematic break
---
Blockquote
> text — renders as info callout
If you're looking for a strictly standard, 1:1 markdown renderer, blogkit-md might not be what you expect.
Instead of building just another plain document viewer, intentional design liberties have been taken to render markdown as beautiful, engaging blog posts.
Documentation shouldn't be a wall of boring text. The goal of this tool is to make reading technical docs, articles, and guides an exciting and visually pleasing experience.
Output
Styled blog post
Raw document
Typography
Optimized for long-form reading
Unstyled
The markdown file is parsed into an AST using remark-parse + remark-gfm, then transformed into React components from @san-siva/blogkit.
Diagram Loading...
In blogkit-md, headings aren't just for changing font sizes—they are the architectural blueprint for your post. Each heading level acts as a layout trigger, directly controlling how BlogSection components are generated, nested, or promoted.
# H1
Page Title. Sets the main article title. Does not generate a structural section block.
## H2
Main Section. Creates a new, top-level BlogSection.
### H3
Subsection. Nests cleanly within the currently active H2 section.
#### H4
Section Break. Renders as a bold line, but acts as a layout trigger: it forces the next H3 to break out and become a brand-new, top-level section.
##### H5 & ###### H6
Inline Emphasis. Renders as a bold line within the current section or subsection without altering the page layout.
Standard content—such as paragraphs, lists, and code blocks—automatically flows into the most recently opened section or subsection.
Because blogkit-md is optimized for blog readability, it includes smart fallbacks to ensure your layout looks great even in edge cases:
Strictly Deepening Hierarchy
Headings within a section must always go deeper (e.g., H2 → H3 → H4). If the hierarchy reverses—like an H3 appearing after an H4—the nesting breaks, and the H3 is promoted to a brand-new top-level section.
H1 loses structural significance if not at the top
If an H1 appears anywhere other than the very top of the document, it does not create a page title. Instead, it is treated as stylized text and rendered as a section break.
Intro section
Any text written before the first heading—or directly beneath the # H1 page title—is automatically grouped into an untitled, top-level BlogSection
Let's put those layout rules into practice. Here is how a standard markdown document translates into a blog layout:
# My Awesome Blog Post
This text becomes the Preamble (an untitled, top-level section).
## The Setup
Some content goes here.
### Prerequisites
Nested content belongs here.
## The Execution
#### Note on performance:
### The ResultsHere is how the parser breaks the above document down into isolated React components:
Intro section
This text becomes an introductory, untitled section.Section 1
## The Setup
Some content goes here.
#### Prerequisites
Nested content belongs here.Section 2
## The Execution
#### Note on performance:Section 3
## The Resultsblogkit-md is just one piece of the puzzle. If you want to customize the underlying React components, tweak the UI, or take full control over your blog's layout, dive into the official Blogkit documentation.
blogkit-md is open source software licensed under the MIT license.
Contributions are welcome!
Author: Santhosh Siva
License: MIT
A Next.js tool that converts standard markdown files into rendered blog posts for @san-siva/blogkit.
Note: This blog post is translated from the README.md file in the blogkit-md repository.
git clone https://github.com/san-siva/blogkit-md.git
npm installnpm run dev # uses data/test.md by default
npm run dev -- --file=data/my-post.md # specify a markdown fileThe dev server watches the markdown file for changes and auto-reloads the browser via HMR.
npm run build
npm run startnpm run lint # check
npm run fix # auto-fixblogkit-md exposes a BlogPost server component you can drop into any Next.js project.
npm install @san-siva/blogkit-mdOr as a local package:
"@san-siva/blogkit-md": "file:../blogkit-md"Add it to transpilePackages in your next.config.ts:
const nextConfig = {
transpilePackages: ['@san-siva/blogkit-md'],
};import { BlogPost } from '@san-siva/blogkit-md';
export default function Page() {
return (
<BlogPost
filePath="content/my-post.md"
jsonLd={{
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: 'My Post',
description: 'Post description',
datePublished: '2026-01-01',
author: { '@type': 'Person', name: 'Your Name' },
}}
/>
);
}filePath
string
Yes
Path to the markdown file. Relative paths are resolved from process.cwd().
jsonLd
WithContext<Thing>
No
Optional JSON-LD schema passed to <Blog> for structured data / SEO.
Headings
# H1 ## H2 ### H3 #### H4
Paragraph
Plain text
Hard line break
Two spaces at end of line
Bold
**bold**
Italic
_italic_
Inline code
`code`
Link
[text](url)
Image

Ordered list
1. item
Unordered list
- item
Table
GFM table syntax
Code block
```lang
Mermaid diagram
```mermaid
Thematic break
---
Blockquote
> text — renders as info callout
If you're looking for a strictly standard, 1:1 markdown renderer, blogkit-md might not be what you expect.
Instead of building just another plain document viewer, intentional design liberties have been taken to render markdown as beautiful, engaging blog posts.
Documentation shouldn't be a wall of boring text. The goal of this tool is to make reading technical docs, articles, and guides an exciting and visually pleasing experience.
Output
Styled blog post
Raw document
Typography
Optimized for long-form reading
Unstyled
The markdown file is parsed into an AST using remark-parse + remark-gfm, then transformed into React components from @san-siva/blogkit.
Diagram Loading...
In blogkit-md, headings aren't just for changing font sizes—they are the architectural blueprint for your post. Each heading level acts as a layout trigger, directly controlling how BlogSection components are generated, nested, or promoted.
# H1
Page Title. Sets the main article title. Does not generate a structural section block.
## H2
Main Section. Creates a new, top-level BlogSection.
### H3
Subsection. Nests cleanly within the currently active H2 section.
#### H4
Section Break. Renders as a bold line, but acts as a layout trigger: it forces the next H3 to break out and become a brand-new, top-level section.
##### H5 & ###### H6
Inline Emphasis. Renders as a bold line within the current section or subsection without altering the page layout.
Standard content—such as paragraphs, lists, and code blocks—automatically flows into the most recently opened section or subsection.
Because blogkit-md is optimized for blog readability, it includes smart fallbacks to ensure your layout looks great even in edge cases:
Strictly Deepening Hierarchy
Headings within a section must always go deeper (e.g., H2 → H3 → H4). If the hierarchy reverses—like an H3 appearing after an H4—the nesting breaks, and the H3 is promoted to a brand-new top-level section.
H1 loses structural significance if not at the top
If an H1 appears anywhere other than the very top of the document, it does not create a page title. Instead, it is treated as stylized text and rendered as a section break.
Intro section
Any text written before the first heading—or directly beneath the # H1 page title—is automatically grouped into an untitled, top-level BlogSection
Let's put those layout rules into practice. Here is how a standard markdown document translates into a blog layout:
# My Awesome Blog Post
This text becomes the Preamble (an untitled, top-level section).
## The Setup
Some content goes here.
### Prerequisites
Nested content belongs here.
## The Execution
#### Note on performance:
### The ResultsHere is how the parser breaks the above document down into isolated React components:
Intro section
This text becomes an introductory, untitled section.Section 1
## The Setup
Some content goes here.
#### Prerequisites
Nested content belongs here.Section 2
## The Execution
#### Note on performance:Section 3
## The Resultsblogkit-md is just one piece of the puzzle. If you want to customize the underlying React components, tweak the UI, or take full control over your blog's layout, dive into the official Blogkit documentation.
blogkit-md is open source software licensed under the MIT license.
Contributions are welcome!
Author: Santhosh Siva
License: MIT
A Next.js tool that converts standard markdown files into rendered blog posts for @san-siva/blogkit.
Note: This blog post is translated from the README.md file in the blogkit-md repository.
1git clone https://github.com/san-siva/blogkit-md.git
2npm install1npm run dev # uses data/test.md by default
2npm run dev -- --file=data/my-post.md # specify a markdown fileThe dev server watches the markdown file for changes and auto-reloads the browser via HMR.
1npm run build
2npm run startnpm run lint # check
npm run fix # auto-fix1git clone https://github.com/san-siva/blogkit-md.git
2npm install1npm run dev # uses data/test.md by default
2npm run dev -- --file=data/my-post.md # specify a markdown fileThe dev server watches the markdown file for changes and auto-reloads the browser via HMR.
1npm run dev # uses data/test.md by default
2npm run dev -- --file=data/my-post.md # specify a markdown file1npm run build
2npm run start1npm run build
2npm run start1npm run lint # check
2npm run fix # auto-fix1npm run lint # check
2npm run fix # auto-fixblogkit-md exposes a BlogPost server component you can drop into any Next.js project.
1npm install @san-siva/blogkit-mdOr as a local package:
1"@san-siva/blogkit-md": "file:../blogkit-md"Add it to transpilePackages in your next.config.ts:
const nextConfig = {
transpilePackages: ['@san-siva/blogkit-md'],
};import { BlogPost } from '@san-siva/blogkit-md';
export default function Page() {
return (
<BlogPost
filePath="content/my-post.md"
jsonLd={{
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: 'My Post',
description: 'Post description',
datePublished: '2026-01-01',
author: { '@type': 'Person', name: 'Your Name' },
}}
/>
);
}filePath
string
Yes
Path to the markdown file. Relative paths are resolved from process.cwd().
jsonLd
WithContext<Thing>
No
Optional JSON-LD schema passed to <Blog> for structured data / SEO.
1npm install @san-siva/blogkit-mdOr as a local package:
1"@san-siva/blogkit-md": "file:../blogkit-md"Add it to transpilePackages in your next.config.ts:
1const nextConfig = {
2 transpilePackages: ['@san-siva/blogkit-md'],
3};1npm install @san-siva/blogkit-md1"@san-siva/blogkit-md": "file:../blogkit-md"1const nextConfig = {
2 transpilePackages: ['@san-siva/blogkit-md'],
3};import { BlogPost } from '@san-siva/blogkit-md';
export default function Page() {
return (
<BlogPost
filePath="content/my-post.md"
jsonLd={{
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: 'My Post',
description: 'Post description',
datePublished: '2026-01-01',
author: { '@type': 'Person', name: 'Your Name' },
}}
/>
);
}1import { BlogPost } from '@san-siva/blogkit-md';
2
3export default function Page() {
4 return (
5 <BlogPost
6 filePath="content/my-post.md"
7 jsonLd={{
8 '@context': 'https://schema.org',
9 '@type': 'BlogPosting',
10 headline: 'My Post',
11 description: 'Post description',
12 datePublished: '2026-01-01',
13 author: { '@type': 'Person', name: 'Your Name' },
14 }}
15 />
16 );
17}filePath
string
Yes
Path to the markdown file. Relative paths are resolved from process.cwd().
jsonLd
WithContext<Thing>
No
Optional JSON-LD schema passed to <Blog> for structured data / SEO.
Headings
# H1 ## H2 ### H3 #### H4
Paragraph
Plain text
Hard line break
Two spaces at end of line
Bold
**bold**
Italic
_italic_
Inline code
`code`
Link
[text](url)
Image

Ordered list
1. item
Unordered list
- item
Table
GFM table syntax
Code block
```lang
Mermaid diagram
```mermaid
Thematic break
---
Blockquote
> text — renders as info callout
If you're looking for a strictly standard, 1:1 markdown renderer, blogkit-md might not be what you expect.
Instead of building just another plain document viewer, intentional design liberties have been taken to render markdown as beautiful, engaging blog posts.
Documentation shouldn't be a wall of boring text. The goal of this tool is to make reading technical docs, articles, and guides an exciting and visually pleasing experience.
Output
Styled blog post
Raw document
Typography
Optimized for long-form reading
Unstyled
If you're looking for a strictly standard, 1:1 markdown renderer, blogkit-md might not be what you expect.
Instead of building just another plain document viewer, intentional design liberties have been taken to render markdown as beautiful, engaging blog posts.
Documentation shouldn't be a wall of boring text. The goal of this tool is to make reading technical docs, articles, and guides an exciting and visually pleasing experience.
Output
Styled blog post
Raw document
Typography
Optimized for long-form reading
Unstyled
The markdown file is parsed into an AST using remark-parse + remark-gfm, then transformed into React components from @san-siva/blogkit.
Diagram Loading...
In blogkit-md, headings aren't just for changing font sizes—they are the architectural blueprint for your post. Each heading level acts as a layout trigger, directly controlling how BlogSection components are generated, nested, or promoted.
# H1
Page Title. Sets the main article title. Does not generate a structural section block.
## H2
Main Section. Creates a new, top-level BlogSection.
### H3
Subsection. Nests cleanly within the currently active H2 section.
#### H4
Section Break. Renders as a bold line, but acts as a layout trigger: it forces the next H3 to break out and become a brand-new, top-level section.
##### H5 & ###### H6
Inline Emphasis. Renders as a bold line within the current section or subsection without altering the page layout.
Standard content—such as paragraphs, lists, and code blocks—automatically flows into the most recently opened section or subsection.
Because blogkit-md is optimized for blog readability, it includes smart fallbacks to ensure your layout looks great even in edge cases:
Strictly Deepening Hierarchy
Headings within a section must always go deeper (e.g., H2 → H3 → H4). If the hierarchy reverses—like an H3 appearing after an H4—the nesting breaks, and the H3 is promoted to a brand-new top-level section.
H1 loses structural significance if not at the top
If an H1 appears anywhere other than the very top of the document, it does not create a page title. Instead, it is treated as stylized text and rendered as a section break.
Intro section
Any text written before the first heading—or directly beneath the # H1 page title—is automatically grouped into an untitled, top-level BlogSection
Let's put those layout rules into practice. Here is how a standard markdown document translates into a blog layout:
# My Awesome Blog Post
This text becomes the Preamble (an untitled, top-level section).
## The Setup
Some content goes here.
### Prerequisites
Nested content belongs here.
## The Execution
#### Note on performance:
### The ResultsHere is how the parser breaks the above document down into isolated React components:
Intro section
This text becomes an introductory, untitled section.Section 1
## The Setup
Some content goes here.
#### Prerequisites
Nested content belongs here.Section 2
## The Execution
#### Note on performance:Section 3
## The ResultsIn blogkit-md, headings aren't just for changing font sizes—they are the architectural blueprint for your post. Each heading level acts as a layout trigger, directly controlling how BlogSection components are generated, nested, or promoted.
# H1
Page Title. Sets the main article title. Does not generate a structural section block.
## H2
Main Section. Creates a new, top-level BlogSection.
### H3
Subsection. Nests cleanly within the currently active H2 section.
#### H4
Section Break. Renders as a bold line, but acts as a layout trigger: it forces the next H3 to break out and become a brand-new, top-level section.
##### H5 & ###### H6
Inline Emphasis. Renders as a bold line within the current section or subsection without altering the page layout.
Standard content—such as paragraphs, lists, and code blocks—automatically flows into the most recently opened section or subsection.
Because blogkit-md is optimized for blog readability, it includes smart fallbacks to ensure your layout looks great even in edge cases:
Strictly Deepening Hierarchy
Headings within a section must always go deeper (e.g., H2 → H3 → H4). If the hierarchy reverses—like an H3 appearing after an H4—the nesting breaks, and the H3 is promoted to a brand-new top-level section.
H1 loses structural significance if not at the top
If an H1 appears anywhere other than the very top of the document, it does not create a page title. Instead, it is treated as stylized text and rendered as a section break.
Intro section
Any text written before the first heading—or directly beneath the # H1 page title—is automatically grouped into an untitled, top-level BlogSection
Let's put those layout rules into practice. Here is how a standard markdown document translates into a blog layout:
1# My Awesome Blog Post
2
3This text becomes the Preamble (an untitled, top-level section).
4
5## The Setup
6
7Some content goes here.
8
9### Prerequisites
10
11Nested content belongs here.
12
13## The Execution
14
15#### Note on performance:
16
17### The ResultsHere is how the parser breaks the above document down into isolated React components:
Intro section
1This text becomes an introductory, untitled section.Section 1
## The Setup
Some content goes here.
#### Prerequisites
Nested content belongs here.Section 2
## The Execution
#### Note on performance:Section 3
## The Results1# My Awesome Blog Post
2
3This text becomes the Preamble (an untitled, top-level section).
4
5## The Setup
6
7Some content goes here.
8
9### Prerequisites
10
11Nested content belongs here.
12
13## The Execution
14
15#### Note on performance:
16
17### The Results1This text becomes an introductory, untitled section.1## The Setup
2
3Some content goes here.
4
5#### Prerequisites
6
7Nested content belongs here.1## The Execution
2
3#### Note on performance:1## The Resultsblogkit-md is just one piece of the puzzle. If you want to customize the underlying React components, tweak the UI, or take full control over your blog's layout, dive into the official Blogkit documentation.
blogkit-md is open source software licensed under the MIT license.
Contributions are welcome!
Author: Santhosh Siva
License: MIT
A Next.js tool that converts standard markdown files into rendered blog posts for @san-siva/blogkit.
Note: This blog post is translated from the README.md file in the blogkit-md repository.
1git clone https://github.com/san-siva/blogkit-md.git
2npm install1npm run dev # uses data/test.md by default
2npm run dev -- --file=data/my-post.md # specify a markdown fileThe dev server watches the markdown file for changes and auto-reloads the browser via HMR.
1npm run build
2npm run startnpm run lint # check
npm run fix # auto-fix1git clone https://github.com/san-siva/blogkit-md.git
2npm install1npm run dev # uses data/test.md by default
2npm run dev -- --file=data/my-post.md # specify a markdown fileThe dev server watches the markdown file for changes and auto-reloads the browser via HMR.
1npm run dev # uses data/test.md by default
2npm run dev -- --file=data/my-post.md # specify a markdown file1npm run build
2npm run start1npm run build
2npm run start1npm run lint # check
2npm run fix # auto-fix1npm run lint # check
2npm run fix # auto-fixblogkit-md exposes a BlogPost server component you can drop into any Next.js project.
1npm install @san-siva/blogkit-mdOr as a local package:
1"@san-siva/blogkit-md": "file:../blogkit-md"Add it to transpilePackages in your next.config.ts:
const nextConfig = {
transpilePackages: ['@san-siva/blogkit-md'],
};import { BlogPost } from '@san-siva/blogkit-md';
export default function Page() {
return (
<BlogPost
filePath="content/my-post.md"
jsonLd={{
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: 'My Post',
description: 'Post description',
datePublished: '2026-01-01',
author: { '@type': 'Person', name: 'Your Name' },
}}
/>
);
}filePath
string
Yes
Path to the markdown file. Relative paths are resolved from process.cwd().
jsonLd
WithContext<Thing>
No
Optional JSON-LD schema passed to <Blog> for structured data / SEO.
1npm install @san-siva/blogkit-mdOr as a local package:
1"@san-siva/blogkit-md": "file:../blogkit-md"Add it to transpilePackages in your next.config.ts:
1const nextConfig = {
2 transpilePackages: ['@san-siva/blogkit-md'],
3};1npm install @san-siva/blogkit-md1"@san-siva/blogkit-md": "file:../blogkit-md"1const nextConfig = {
2 transpilePackages: ['@san-siva/blogkit-md'],
3};import { BlogPost } from '@san-siva/blogkit-md';
export default function Page() {
return (
<BlogPost
filePath="content/my-post.md"
jsonLd={{
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: 'My Post',
description: 'Post description',
datePublished: '2026-01-01',
author: { '@type': 'Person', name: 'Your Name' },
}}
/>
);
}1import { BlogPost } from '@san-siva/blogkit-md';
2
3export default function Page() {
4 return (
5 <BlogPost
6 filePath="content/my-post.md"
7 jsonLd={{
8 '@context': 'https://schema.org',
9 '@type': 'BlogPosting',
10 headline: 'My Post',
11 description: 'Post description',
12 datePublished: '2026-01-01',
13 author: { '@type': 'Person', name: 'Your Name' },
14 }}
15 />
16 );
17}filePath
string
Yes
Path to the markdown file. Relative paths are resolved from process.cwd().
jsonLd
WithContext<Thing>
No
Optional JSON-LD schema passed to <Blog> for structured data / SEO.
Headings
# H1 ## H2 ### H3 #### H4
Paragraph
Plain text
Hard line break
Two spaces at end of line
Bold
**bold**
Italic
_italic_
Inline code
`code`
Link
[text](url)
Image

Ordered list
1. item
Unordered list
- item
Table
GFM table syntax
Code block
```lang
Mermaid diagram
```mermaid
Thematic break
---
Blockquote
> text — renders as info callout
If you're looking for a strictly standard, 1:1 markdown renderer, blogkit-md might not be what you expect.
Instead of building just another plain document viewer, intentional design liberties have been taken to render markdown as beautiful, engaging blog posts.
Documentation shouldn't be a wall of boring text. The goal of this tool is to make reading technical docs, articles, and guides an exciting and visually pleasing experience.
Output
Styled blog post
Raw document
Typography
Optimized for long-form reading
Unstyled
If you're looking for a strictly standard, 1:1 markdown renderer, blogkit-md might not be what you expect.
Instead of building just another plain document viewer, intentional design liberties have been taken to render markdown as beautiful, engaging blog posts.
Documentation shouldn't be a wall of boring text. The goal of this tool is to make reading technical docs, articles, and guides an exciting and visually pleasing experience.
Output
Styled blog post
Raw document
Typography
Optimized for long-form reading
Unstyled
The markdown file is parsed into an AST using remark-parse + remark-gfm, then transformed into React components from @san-siva/blogkit.
Diagram Loading...
In blogkit-md, headings aren't just for changing font sizes—they are the architectural blueprint for your post. Each heading level acts as a layout trigger, directly controlling how BlogSection components are generated, nested, or promoted.
# H1
Page Title. Sets the main article title. Does not generate a structural section block.
## H2
Main Section. Creates a new, top-level BlogSection.
### H3
Subsection. Nests cleanly within the currently active H2 section.
#### H4
Section Break. Renders as a bold line, but acts as a layout trigger: it forces the next H3 to break out and become a brand-new, top-level section.
##### H5 & ###### H6
Inline Emphasis. Renders as a bold line within the current section or subsection without altering the page layout.
Standard content—such as paragraphs, lists, and code blocks—automatically flows into the most recently opened section or subsection.
Because blogkit-md is optimized for blog readability, it includes smart fallbacks to ensure your layout looks great even in edge cases:
Strictly Deepening Hierarchy
Headings within a section must always go deeper (e.g., H2 → H3 → H4). If the hierarchy reverses—like an H3 appearing after an H4—the nesting breaks, and the H3 is promoted to a brand-new top-level section.
H1 loses structural significance if not at the top
If an H1 appears anywhere other than the very top of the document, it does not create a page title. Instead, it is treated as stylized text and rendered as a section break.
Intro section
Any text written before the first heading—or directly beneath the # H1 page title—is automatically grouped into an untitled, top-level BlogSection
Let's put those layout rules into practice. Here is how a standard markdown document translates into a blog layout:
# My Awesome Blog Post
This text becomes the Preamble (an untitled, top-level section).
## The Setup
Some content goes here.
### Prerequisites
Nested content belongs here.
## The Execution
#### Note on performance:
### The ResultsHere is how the parser breaks the above document down into isolated React components:
Intro section
This text becomes an introductory, untitled section.Section 1
## The Setup
Some content goes here.
#### Prerequisites
Nested content belongs here.Section 2
## The Execution
#### Note on performance:Section 3
## The ResultsIn blogkit-md, headings aren't just for changing font sizes—they are the architectural blueprint for your post. Each heading level acts as a layout trigger, directly controlling how BlogSection components are generated, nested, or promoted.
# H1
Page Title. Sets the main article title. Does not generate a structural section block.
## H2
Main Section. Creates a new, top-level BlogSection.
### H3
Subsection. Nests cleanly within the currently active H2 section.
#### H4
Section Break. Renders as a bold line, but acts as a layout trigger: it forces the next H3 to break out and become a brand-new, top-level section.
##### H5 & ###### H6
Inline Emphasis. Renders as a bold line within the current section or subsection without altering the page layout.
Standard content—such as paragraphs, lists, and code blocks—automatically flows into the most recently opened section or subsection.
Because blogkit-md is optimized for blog readability, it includes smart fallbacks to ensure your layout looks great even in edge cases:
Strictly Deepening Hierarchy
Headings within a section must always go deeper (e.g., H2 → H3 → H4). If the hierarchy reverses—like an H3 appearing after an H4—the nesting breaks, and the H3 is promoted to a brand-new top-level section.
H1 loses structural significance if not at the top
If an H1 appears anywhere other than the very top of the document, it does not create a page title. Instead, it is treated as stylized text and rendered as a section break.
Intro section
Any text written before the first heading—or directly beneath the # H1 page title—is automatically grouped into an untitled, top-level BlogSection
Let's put those layout rules into practice. Here is how a standard markdown document translates into a blog layout:
1# My Awesome Blog Post
2
3This text becomes the Preamble (an untitled, top-level section).
4
5## The Setup
6
7Some content goes here.
8
9### Prerequisites
10
11Nested content belongs here.
12
13## The Execution
14
15#### Note on performance:
16
17### The ResultsHere is how the parser breaks the above document down into isolated React components:
Intro section
1This text becomes an introductory, untitled section.Section 1
## The Setup
Some content goes here.
#### Prerequisites
Nested content belongs here.Section 2
## The Execution
#### Note on performance:Section 3
## The Results1# My Awesome Blog Post
2
3This text becomes the Preamble (an untitled, top-level section).
4
5## The Setup
6
7Some content goes here.
8
9### Prerequisites
10
11Nested content belongs here.
12
13## The Execution
14
15#### Note on performance:
16
17### The Results1This text becomes an introductory, untitled section.1## The Setup
2
3Some content goes here.
4
5#### Prerequisites
6
7Nested content belongs here.1## The Execution
2
3#### Note on performance:1## The Resultsblogkit-md is just one piece of the puzzle. If you want to customize the underlying React components, tweak the UI, or take full control over your blog's layout, dive into the official Blogkit documentation.
blogkit-md is open source software licensed under the MIT license.
Contributions are welcome!
Author: Santhosh Siva
License: MIT
1npm run lint # check
2npm run fix # auto-fix1const nextConfig = {
2 transpilePackages: ['@san-siva/blogkit-md'],
3};1import { BlogPost } from '@san-siva/blogkit-md';
2
3export default function Page() {
4 return (
5 <BlogPost
6 filePath="content/my-post.md"
7 jsonLd={{
8 '@context': 'https://schema.org',
9 '@type': 'BlogPosting',
10 headline: 'My Post',
11 description: 'Post description',
12 datePublished: '2026-01-01',
13 author: { '@type': 'Person', name: 'Your Name' },
14 }}
15 />
16 );
17}filePath
string
Yes
Path to the markdown file. Relative paths are resolved from process.cwd().
jsonLd
WithContext<Thing>
No
Optional JSON-LD schema passed to <Blog> for structured data / SEO.
1import { BlogPost } from '@san-siva/blogkit-md';
2
3export default function Page() {
4 return (
5 <BlogPost
6 filePath="content/my-post.md"
7 jsonLd={{
8 '@context': 'https://schema.org',
9 '@type': 'BlogPosting',
10 headline: 'My Post',
11 description: 'Post description',
12 datePublished: '2026-01-01',
13 author: { '@type': 'Person', name: 'Your Name' },
14 }}
15 />
16 );
17}Because blogkit-md is optimized for blog readability, it includes smart fallbacks to ensure your layout looks great even in edge cases:
Strictly Deepening Hierarchy
Headings within a section must always go deeper (e.g., H2 → H3 → H4). If the hierarchy reverses—like an H3 appearing after an H4—the nesting breaks, and the H3 is promoted to a brand-new top-level section.
H1 loses structural significance if not at the top
If an H1 appears anywhere other than the very top of the document, it does not create a page title. Instead, it is treated as stylized text and rendered as a section break.
Intro section
Any text written before the first heading—or directly beneath the # H1 page title—is automatically grouped into an untitled, top-level BlogSection
Let's put those layout rules into practice. Here is how a standard markdown document translates into a blog layout:
1# My Awesome Blog Post
2
3This text becomes the Preamble (an untitled, top-level section).
4
5## The Setup
6
7Some content goes here.
8
9### Prerequisites
10
11Nested content belongs here.
12
13## The Execution
14
15#### Note on performance:
16
17### The ResultsHere is how the parser breaks the above document down into isolated React components:
Intro section
1This text becomes an introductory, untitled section.Section 1
## The Setup
Some content goes here.
#### Prerequisites
Nested content belongs here.Section 2
## The Execution
#### Note on performance:Section 3
## The Results1# My Awesome Blog Post
2
3This text becomes the Preamble (an untitled, top-level section).
4
5## The Setup
6
7Some content goes here.
8
9### Prerequisites
10
11Nested content belongs here.
12
13## The Execution
14
15#### Note on performance:
16
17### The Results1This text becomes an introductory, untitled section.1## The Setup
2
3Some content goes here.
4
5#### Prerequisites
6
7Nested content belongs here.1## The Execution
2
3#### Note on performance:1## The Results1## The Setup
2
3Some content goes here.
4
5#### Prerequisites
6
7Nested content belongs here.1## The Execution
2
3#### Note on performance:1## The Results1npm run lint # check
2npm run fix # auto-fix1const nextConfig = {
2 transpilePackages: ['@san-siva/blogkit-md'],
3};1import { BlogPost } from '@san-siva/blogkit-md';
2
3export default function Page() {
4 return (
5 <BlogPost
6 filePath="content/my-post.md"
7 jsonLd={{
8 '@context': 'https://schema.org',
9 '@type': 'BlogPosting',
10 headline: 'My Post',
11 description: 'Post description',
12 datePublished: '2026-01-01',
13 author: { '@type': 'Person', name: 'Your Name' },
14 }}
15 />
16 );
17}filePath
string
Yes
Path to the markdown file. Relative paths are resolved from process.cwd().
jsonLd
WithContext<Thing>
No
Optional JSON-LD schema passed to <Blog> for structured data / SEO.
1import { BlogPost } from '@san-siva/blogkit-md';
2
3export default function Page() {
4 return (
5 <BlogPost
6 filePath="content/my-post.md"
7 jsonLd={{
8 '@context': 'https://schema.org',
9 '@type': 'BlogPosting',
10 headline: 'My Post',
11 description: 'Post description',
12 datePublished: '2026-01-01',
13 author: { '@type': 'Person', name: 'Your Name' },
14 }}
15 />
16 );
17}Because blogkit-md is optimized for blog readability, it includes smart fallbacks to ensure your layout looks great even in edge cases:
Strictly Deepening Hierarchy
Headings within a section must always go deeper (e.g., H2 → H3 → H4). If the hierarchy reverses—like an H3 appearing after an H4—the nesting breaks, and the H3 is promoted to a brand-new top-level section.
H1 loses structural significance if not at the top
If an H1 appears anywhere other than the very top of the document, it does not create a page title. Instead, it is treated as stylized text and rendered as a section break.
Intro section
Any text written before the first heading—or directly beneath the # H1 page title—is automatically grouped into an untitled, top-level BlogSection
Let's put those layout rules into practice. Here is how a standard markdown document translates into a blog layout:
1# My Awesome Blog Post
2
3This text becomes the Preamble (an untitled, top-level section).
4
5## The Setup
6
7Some content goes here.
8
9### Prerequisites
10
11Nested content belongs here.
12
13## The Execution
14
15#### Note on performance:
16
17### The ResultsHere is how the parser breaks the above document down into isolated React components:
Intro section
1This text becomes an introductory, untitled section.Section 1
## The Setup
Some content goes here.
#### Prerequisites
Nested content belongs here.Section 2
## The Execution
#### Note on performance:Section 3
## The Results1# My Awesome Blog Post
2
3This text becomes the Preamble (an untitled, top-level section).
4
5## The Setup
6
7Some content goes here.
8
9### Prerequisites
10
11Nested content belongs here.
12
13## The Execution
14
15#### Note on performance:
16
17### The Results1This text becomes an introductory, untitled section.1## The Setup
2
3Some content goes here.
4
5#### Prerequisites
6
7Nested content belongs here.1## The Execution
2
3#### Note on performance:1## The Results1## The Setup
2
3Some content goes here.
4
5#### Prerequisites
6
7Nested content belongs here.1## The Execution
2
3#### Note on performance:1## The Results1## The Setup
2
3Some content goes here.
4
5#### Prerequisites
6
7Nested content belongs here.1## The Execution
2
3#### Note on performance:1## The Results1## The Setup
2
3Some content goes here.
4
5#### Prerequisites
6
7Nested content belongs here.1## The Execution
2
3#### Note on performance:1## The Results