A minimalist multilingual static blog template built on Astro, with no CSS / UI framework dependencies.
View Live Demo · Lighthouse 100/100 Report
- High-Performance Minimal Architecture: Built on Astro Static Site Generation (SSG), with no CSS / UI framework dependencies. Achieves a perfect 100/100 Lighthouse score across all categories.
- Internationalization (i18n) & SEO:
- Built-in Simplified Chinese, English, and Japanese translations, powered by
ts-intl-astro. - Subpath-based static multilingual routing (e.g.,
/zh-Hans/,/en-US/,/ja-JP/). - Smart language redirect: automatically selects the site language based on language preference cookie or browser language.
- Automatic generation of multilingual SEO tags (
hreflang/x-default/ Open Graph). - Automatic generation of sitemap,
robots.txt, and per-language RSS feeds.
- Built-in Simplified Chinese, English, and Japanese translations, powered by
- Offline Full-Text Search: Integrated Pagefind static search engine, zero configuration required.
- Modern Markdown / MDX Writing Experience:
- Type-safe content collections based on Zod and Astro Content Layer.
- Code highlighting powered by Expressive Code.
- Built-in utility MDX components: file tree (
FileTree), step-by-step instructions (Steps), tabs (Tabs), and GitHub-style alert blockquotes (remark-github-blockquote-alert) .
- Other Features: Support for Disqus comment system and Microsoft Clarity site analytics.
-
Clone the repository:
git clone https://github.com/Aaakul/astro-plain.git cd astro-plain -
Install dependencies:
# npm npm install # pnpm pnpm install # bun bun install
-
Start the development server:
# npm npm run dev # pnpm pnpm run dev # bun bun --bun run dev
The development server runs at
http://127.0.0.1:4321by default.
Note
Pagefind relies on static build output to generate its index. You must run the build command at least once before using it in the development environment for the first time.
After adding or modifying posts, the dev server will not automatically regenerate the search index.
The core configuration file is site.config.ts, with key options as follows:
| Option | Description | Default |
|---|---|---|
defaultLanguage |
Default language code | "zh-Hans" |
siteUrl |
Site URL (can also be set via environment variable SITE_URL) |
"http://127.0.0.1:4321" |
basePath |
Subpath deployment prefix (can also be set via environment variable BASE_PATH) |
"" |
languageNameMap |
Mapping of language codes to display names | See config file |
postsPerPage |
Number of posts per page in the blog list | 5 |
navLinks |
Top navigation bar links | See config file |
ogImage |
Default social sharing image (OG Image), recommended size 1200x630 | "/static/images/og.jpg" |
allowRobots |
Whether to allow crawlers | true |
disqus |
Disqus comments (enable + shortname) |
Disabled |
clarity |
Microsoft Clarity (enable + projectId) |
Disabled |
Refer to the comments in .env.example to create a .env file, where you can set SITE_URL, BASE_PATH, as well as Disqus and Clarity services.
Modify the following fields in the translation files i18n/messages/*.ts:
common.header_titlecommon.site_titlecommon.site_description
Replace the following files:
public/favicon.icopublic/favicon.svgpublic/apple-touch-icon.pngpublic/static/images/og.jpgsrc/assets/*
Content files are located in src/content/, with schemas defined in src/content.config.ts.
Corresponding files are located at src/content/mdx/<language-code>/hero.mdx.
Both Markdown and MDX formats are supported. Post Frontmatter example:
---
title: "Post Title" # Required
translationKey: "unique-key" # Required: used to associate posts across different language versions
language: "zh-Hans" # Required: language code, must be declared in languageNameMap
date: "2026-08-30T10:00:00Z" # Required: ISO 8601 format
summary: "Post summary" # Optional: used for list display and SEO
lastmod: "2026-08-30T12:00:00Z" # Optional: last modified date
isCanonical: true # Optional: set as canonical language version (generates x-default/canonical)
draft: false # Optional: drafts are excluded from builds
authors: ["default"] # Optional: author list
categories: ["Tech"] # Optional
tags: ["Astro"] # Optional
image: "@/assets/banner.jpg" # Optional: post cover image
enableComments: false # Optional: whether to enable comments, defaults to true
---Note
Multilingual association (translationKey): For the same post in different languages, declare the same translationKey in their respective Frontmatter, and the template will automatically generate language switcher links and hreflang tags.
The default author file is default.mdx. Example:
---
name: "Author Name" # Required
language: "zh-Hans" # Required
avatar: "@/assets/avatar.svg"
occupation: "Occupation"
company: "Company Name"
email: "hello@example.com"
link:
github: "https://github.com/username"
------
name: "Astro Plain" # Required: project title
language: "zh-Hans" # Required: language code
website: "https://example.com"
image: "@/assets/project-preview.png"
link:
github: "https://github.com/Aaakul/astro-plain"
---
Body content...- Add the language code to
languageNameMapinsite.config.ts(e.g.,"fr-FR": "Français"). - Create the corresponding translation dictionary file under
i18n/messages/(e.g.,fr-FR.ts). - Import and register the dictionary in
createI18nini18n/index.ts. - Create an author file containing at least
default.mdxundersrc/content/author/<language-code>/.
The project outputs pure static files upon build completion, with the output directory being dist.
-
Fork this repository to your own GitHub account.
-
Log in to the Cloudflare Dashboard, click Compute -> Workers and Pages -> Create Application -> Continue to Pages, and connect your GitHub repository.
-
Configure build settings:
-
Build command:
npm run build
-
Build output directory:
dist -
Environment variables: Set
SITE_URLto the domain after deployment (e.g.,https://example.pages.dev), and configure Disqus and Clarity variables as needed.
-
-
Save and deploy. Any subsequent push to the
mainbranch will automatically trigger a new build and deployment.
This project is open-sourced under the MIT License. Stars, PRs, and Issues are welcome.
