Astro Jing is a calm blog theme powered by Astro. This post will show you how to use it.

Features:

  • Auto-generate post descriptions based on character count or up to the <!-- more --> tag
  • Auto-expanding & collapsing table of contents
  • Open Graph image generation
  • Full-text search
  • Syntax highlighting
  • Math equations
  • Internationalization (i18n)
  • Comment systems (Giscus / Disqus)
  • Sitemap & RSS feed
  • Static site
  • View the post as Markdown

Usage

git clone https://github.com/ziteh/astro-jing-theme.git
cd astro-jing-theme
pnpm i
pnpm dev

Markdown

Posts

By default, place your post .md files in the src/content/blog/ directory. Set CONTENT_DIR to use a different content root.

Frontmatter

The YAML frontmatter format for posts broadly compatible with Hexo, the default values for some fields can be changed in the site.ts configuration (with defaultFm prefix).

FieldDescriptionType
title*Post title (h1), also used as the metadata title.string
descriptionPost summary, auto-generated if not given.string
date*Publish datestring in YYYY-MM-DDTHH:mm:ss
updatedUpdated datestring in YYYY-MM-DDTHH:mm:ss
tagsPost tagsArray of strings, default: SITE.defaultFmTag
categoriesPost categoriesArray of strings, default: SITE.defaultFmCategory
draftMark as draft, excludes from productionboolean, default: false
featuredMark as featured postboolean, default: false
tocEnable table of contentsboolean, default: SITE.defaultFmToc
commentsEnable commentsboolean, default: SITE.defaultFmComments
mathEnable math equationsboolean, default: SITE.defaultFmMath

*: required

About

The Markdown for about page is: src/content/about.md.

about.md does not require frontmatter; it is recommended not to include an h1 (i.e. # Header).

Configuration

There are some settings that need to be adjusted before deployment.

site.ts

src/config/site.ts

Basic site information and feature toggles.

FieldDescriptionExample
url*Your site’s URLhttps://username.github.io
title*Blog titleMy Blog
description*Blog descriptionA personal blog
author*Blog author nameZiTe
postsPerHomepagePosts to display per page (home)3
postsPerArchivesPosts to display per page (archives)10
postsPerAllPostsPosts to display per page (posts)5
getDescriptionCountCharacter count for auto-description150
getDescriptionMaxLinesMax lines to process for auto-description10
defaultFmTagDefault tag for postsOthers
defaultFmCategoryDefault category for posts""
defaultFmTocEnable table of contents by defaultfalse
defaultFmCommentsEnable comments by defaultfalse
defaultFmMathEnable math equations by defaultfalse
transitionsEnable view transitionstrue
ogFontPathPath to a local font file for OG images, bypassing the Astro Fonts APIfonts/NotoSansTC-Regular.ttf
postMdUrlGenerate a Markdown version of your blog posts for LLMs to crawltrue
llmsTxtGenerate llms.txt for LLMs to crawl your blog posts (need postMdUrl to be true)false
viewAsMDAdd a “View as Markdown” button to post (need postMdUrl to be true)true
disqusShortnameDisqus shortnameyour-disqus-shortname
giscusRepoGiscus repositoryuser/repo
giscusRepoIdGiscus repository ID
giscusCategoryGiscus category name
giscusCategoryIdGiscus category ID

*: important

lang.ts

src/config/lang.ts

Internationalization (i18n) language and locale settings.

Key settings:

  • lang: BCP 47 language tag (e.g., en, zh-TW)
  • langOg: Open Graph locale tag (e.g., en_US, zh_TW)
  • timeZone: IANA time zone (e.g., America/New_York, Asia/Taipei)

To add a new language, modify the myLang object following the en template and update the exported _t constant.

socials.ts

src/config/socials.ts

Social media links displayed in the site footer.

Each social link object contains:

  • title: Link display text
  • href: URL to the social profile

Example:

{
title: "My GitHub",
href: "https://github.com/username",
}

astro.config.ts

astro.config.ts

Astro config, please refer to Configuration overview and Configuration Reference.

Features

Details of each feature.

Auto-generate Description

If there is no description in the frontmatter, one will be generated automatically. There are two ways this is done:

  1. If there is a <!-- more --> tag, the description will be the content from the first line up to the <!-- more --> tag.
  2. If there is no <!-- more --> tag, the first getDescriptionCount characters will be used.

For performance reasons, only the first getDescriptionMaxLines lines of each .md file will be processed.

You can adjust getDescriptionCount and getDescriptionMaxLines in site.ts.

Fonts

By default, Astro Jing downloads Geist (body) and Fira Mono (code) at build time via Astro’s built-in font API.

If you prefer system-native fonts — for example, to use Traditional Chinese fonts like PingFang TC / Microsoft JhengHei without any web font download — you can switch manually:

  1. astro.config.ts — Remove the --font-body and --font-mono entries from the fonts array. Keep --font-og (Satori needs it to generate OG images).

    fonts: [
    // Remove --font-body and --font-mono entries
    {
    cssVariable: "--font-og",
    name: "Noto Sans",
    weights: [400],
    styles: ["normal"],
    formats: ["woff"],
    provider: fontProviders.fontsource(),
    },
    ],
  2. src/layouts/BaseLayout.astro — Replace the two <Font> tags with an inline style that defines the CSS variables directly:

    <!-- Replace: -->
    <Font cssVariable="--font-body" preload />
    <Font cssVariable="--font-mono" />
    <!-- With: -->
    <style is:inline>
    :root {
    --font-body:
    "PingFang TC", "Microsoft JhengHei", "Noto Sans TC", system-ui, -apple-system,
    BlinkMacSystemFont, "Segoe UI", sans-serif;
    --font-mono:
    ui-monospace, "Cascadia Code", Menlo, Monaco, Consolas, "Courier New", monospace;
    }
    </style>

Use is:inline so Astro does not scope the <style> tag — scoped styles would prevent :root from applying globally.

All other CSS files (global.css, post.css, etc.) already use var(--font-body) and var(--font-mono) and require no changes.

OG image font

OG images are rendered by Satori, which relies solely on the --font-og font’s glyphs — it does not fall back to system fonts. By default --font-og is fetched via the Astro Fonts API, whose default subset only covers Latin characters. If your post titles/tags contain non-Latin characters (e.g. Chinese, Japanese, and Korean) that aren’t in that subset, they will render as missing-glyph boxes in OG images.

To fix this, set ogFontPath in site.ts to the path (relative to the project root) of a local font file that covers the characters you need, e.g.:

ogFontPath: "fonts/NotoSansTC-Regular.ttf",

When ogFontPath is non-empty, that font file is read directly for OG image rendering, bypassing the Astro Fonts API and its subsetting entirely. Leave it as "" to keep using the Astro Fonts API.

Syntax highlighting

Astro Jing uses Expressive Code for syntax highlighting.

You can adjust its config in astro.config.ts. Themes

Example:

astro.config.ts
export default defineConfig({
// ...
integrations: [
expressiveCode({
plugins: [pluginLineNumbers()],
themes: ["catppuccin-latte", "one-dark-pro"],
defaultProps: {
wrap: false,
showLineNumbers: false,
},
}),
// ...
],
});

Deploy

You can easily deploy Astro Jing to a variety of platforms, including GitHub Pages, Netlify, Cloudflare, Vercel, and more, please refer to Deploy your Astro Site.