Note: This article was translated from the original Chinese by an AI.
Many thanks to @mizorewww for providing the template.
He has also given me a great deal of other help along the learning journey – thank you again.
This article is both a writing manual and a "runnable example": every section corresponds to a writing feature the blog supports. You can copy the syntax directly and use it as a template.
Text & Typography
Body text supports normal Markdown syntax. You can use bold, italic, strikethrough, and inline code. The inline code theme has been given low-contrast treatment in both light and dark modes so it doesn't jump out of the paragraph.
Blockquotes use >:
The blog's writing syntax deliberately stays restrained. Shortcodes are only introduced when embedding rich components. For regular articles, just write Markdown – the build step converts these shortcodes into stable MDX components or Shiki code blocks.
Ordered list:
- First item
- Second item
- Nested item
- Another nested item
- Third item
Unordered list:
- Use
-or*– both work - Supports internal links and external links; external links automatically get
target="_blank"andrel="noopener noreferrer" - Auto-links are also supported: https://example.com
Heading Levels
Here we demonstrate levels from H2 to H4 (H1 is reserved for the article title). The table of contents (right-hand TOC) is generated automatically from these headings, with anchor links for jumping.
H3: Third-level heading
Body text.
H4: Fourth-level heading
Body text.
Code Blocks
Code blocks automatically get a title bar: a language icon on the left and a copy button on the right. If a code block carries title metadata, the title bar will display the file name.
type Post = {
slug: string
title: string
date: string
tags: string[]
}
function summarize(post: Post): string {
return `${post.title} · ${post.date} · ${post.tags.join(', ')}`
}Code block with a title and line numbers:
export function pickLatest(posts: Post[]): Post[] {
return [...posts].sort((a, b) => (a.date < b.date ? 1 : -1))
}Different languages automatically switch the icon and accent colour:
yarn install
yarn devdef greet(name: str) -> str:
return f"Hello, {name}!"{
"name": "blog",
"version": "1.0.0",
"private": true
}Icon Shortcode
Inline icons use the :icon-name: syntax, where the name corresponds to a Lucide icon. For example: rocket is :icon-rocket:, code is :icon-code:, tag is :icon-tag:. Icons are replaced with an <Icon> component at build time, adding no runtime cost.
Common icons: :icon-book:, :icon-pencil:, :icon-link:, :icon-github:, :icon-bell:.
GitHub Code Reference
The ::github-code shortcode lets you embed real source code from a repository directly in the article. After rendering, it gets Shiki highlighting, a language icon, and a link to GitHub. The default repository points to omicron0314/blog.
::github-code repo="omicron0314/blog" ref="HEAD" path="contentlayer.config.ts" lines="1-2" lang="ts" title="contentlayer.config.ts"Rendered output:
export { Authors, Blog } from './contentlayer/config/documentTypes'
export { default } from './contentlayer/config/source'Another example embedding lib/utils.ts:
import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}GitHub Diff Reference
::github-diff renders the diff of a specific commit or range, styled line by line as on GitHub.
::github-diff repo="omicron0314/blog" ref="4d2b6dfb6cd6d6b6f8ef139988b2838fe335b8ff" path="css/tailwind.css" lines="1-20"Rendered output:
No diff matched this query.Tables
Tables are automatically wrapped by TableWrapper, allowing them to scroll horizontally on narrow screens.
| Feature | Syntax | Note |
|---|---|---|
| Code block | ```lang | Auto icon + copy |
| Icon | :icon-name: | Lucide |
| GitHub code | ::github-code ... | Local-first |
| GitHub diff | ::github-diff ... | Shiki diff |
| Mini Chart | $AAPL (own line) | Only when entire paragraph |
| Advanced Chart | ::tv AAPL interval=60 | Supports parameters |
Images
Use the normal Markdown image syntax; at render time the image gets wrapped with MDXImage, complete with width/height to prevent CLS.

You can also use the <Image> component directly, which is suitable when you need precise size control.
Market Charts
Single-line ticker → Mini Chart
Writing $AAPL on its own line renders a TradingView Mini Chart. Note: the replacement only happens when the entire paragraph is a single ticker – mentioning $AAPL casually in body text will not trigger it.
$AAPLRendered output:
Crypto assets are also supported:
Advanced Chart Shortcode
::tv followed by a symbol and optional parameters renders a full TradingView Advanced Chart.
::tv AAPL interval=60 height=460Rendered output:
Supported parameters:
interval: candle interval (minutes, e.g.60,240,D,W)height: chart height (pixels)locale: interface languagetimezone: timezone
Frontmatter Field Reference
The YAML frontmatter at the top of an article supports the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Article title |
date | date | Yes | Publish date (YYYY-MM-DD) |
summary | string | No | List/SEO summary |
categories | string[] | No | Categories |
tags | string[] | No | Tags |
language | string | No | Language code (zh/en) |
translationKey | string | No | i18n linkage key |
authors | string[] | No | Author IDs |
image | string | No | Social share image |
images | json | No | Multiple images |
draft | boolean | No | Draft |
lastmod | date | No | Last modified date |
canonicalUrl | string | No | Canonical URL |
layout | string | No | Custom layout |
Multi-language Linking
The Chinese and English versions of the same article are linked via translationKey. For example, this article:
content/blog/zh/blog-features-showcase.mdcontent/blog/en/blog-features-showcase.md
Both share translationKey: blog-features-showcase, and the language switcher will automatically jump to the corresponding version.
Writing Tips
- Use plain Markdown for regular content; don’t stuff too much JSX into the body.
- When referencing source code, prefer
::github-codeover copy-pasting – the code stays up to date with the repository. - Market charts are only for finance-related articles; avoid inserting distracting widgets into technical posts.
- Whenever possible, provide width/height for images. The blog’s
MDXImagedoes this by default, but be mindful of CLS when using custom<img>tags. - Use the
YYYY-MM-DDformat for article dates; the build process parses them into ISO dates for sorting and sitemaps.
Summary
This demo article is itself a “runnable document”: every rendering effect you see corresponds to a piece of syntax in the source code. Save this article as a template – new articles can start by copying and adapting it.
Unless noted otherwise, this post is licensed under CC BY-NC-SA 4.0. Please attribute, use non-commercially, and share adaptations under the same terms.