A modern personal blog interface built with Astro and powered by Ghost CMS API.
Read this in: English | 简体中文 | 日本語
- High-performance static site built with Astro
- Ghost CMS integration (Headless)
- Multi-language support (zh/ja/en) with automatic fallback
- Responsive design with dark/light theme toggle
- Multiple post type displays (articles, gallery, video, music)
- SEO optimized (hreflang, canonical, html lang)
| Document | Description |
|---|---|
| README.md (this file) | User guide - setup and content publishing |
| DEVELOPMENT.md | Developer guide - architecture, testing, workflows, and contributing |
This project uses pnpm.
# (Recommended) Enable pnpm via Corepack
corepack enable pnpm
pnpm installIf
corepackis not available on your system, you can install pnpm globally withnpm i -g pnpm.
Create a .env file from the template:
cp .env.example .envEdit .env with your Ghost instance information:
GHOST_URL=https://your-ghost-instance.com
GHOST_CONTENT_KEY=your-content-api-key-here
GHOST_VERSION=v5.0
GHOST_TIMEOUT=5000
SITE_URL=https://your-site.example.com
IMAGE_HOST_URL=
GOOGLE_ANALYTICS_TAG_ID=| Variable | Required | Description |
|---|---|---|
GHOST_URL |
Yes | Base URL of your Ghost instance |
GHOST_CONTENT_KEY |
Yes | Ghost Content API key |
GHOST_VERSION |
No | Ghost Content API version (default: v5.0) |
GHOST_TIMEOUT |
No | Ghost request timeout in milliseconds (default: 5000) |
SITE_URL |
Yes | Public site URL for canonical and hreflang |
IMAGE_HOST_URL |
No | Optional image host/CDN used for remote image domain allowlist (default: empty) |
GOOGLE_ANALYTICS_TAG_ID |
No | Optional Google tag / GA4 Measurement ID (e.g., G-XXXX). Leave empty to disable analytics |
- Log in to your Ghost Admin panel
- Navigate to Settings → Integrations
- Click Add custom integration
- Copy the Content API Key into your
.envfile
Tip: Use the Ghost Demo API for testing:
GHOST_URL=https://demo.ghost.io GHOST_CONTENT_KEY=22444f78447824223cefc48062
pnpm devVisit http://localhost:4321 to see your site.
| Command | Description |
|---|---|
pnpm dev |
Start the development server |
pnpm build |
Build the production site |
pnpm preview |
Preview the production build |
pnpm astro sync |
Generate type definitions (useful after env/schema changes) |
pnpm astro check |
Typecheck and validate Astro project |
pnpm test |
Run the test suite |
pnpm format |
Format the codebase |
Use regular tags to classify your posts. The system recognizes special prefixes:
| Tag Prefix | Purpose | Example |
|---|---|---|
type- |
Post display type | type-article, type-gallery, type-video, type-music |
category- |
Content category | category-tech, category-life, category-design |
series- |
Article series | series-astro-tutorial, series-web-dev-basics |
| (no prefix) | General tags | JavaScript, React, Photography |
| Type Tag | Display Style |
|---|---|
type-article |
Standard article layout |
type-gallery |
Image gallery with carousel |
type-video |
Video player embed |
type-music |
Audio player embed |
| (default) | Default card layout |
| Route | Description |
|---|---|
/ |
Auto-redirects to user's preferred language |
/zh/ |
Chinese posts listing |
/ja/ |
Japanese posts listing |
/en/ |
English posts listing |
/zh/p/{key}/ |
Chinese version of article |
/ja/p/{key}/ |
Japanese version of article |
/en/p/{key}/ |
English version of article |
Use internal tags (starting with #) in Ghost:
| Internal Tag | Purpose | Example |
|---|---|---|
#lang-{locale} |
Specify post language | #lang-zh, #lang-ja, #lang-en |
#i18n-{key} |
Translation group identifier | #i18n-intro-to-solitude |
Note: In Ghost Content API, internal tags
#xxxare converted to slug formathash-xxx.
Important: Each language version is a separate post in Ghost. They are linked together using the same #i18n-{key} tag.
Choose a unique key for your article, e.g., astro-guide. This key will be used in:
- The
#i18n-astro-guidetag (to link all versions) - The URL:
/zh/p/astro-guide,/ja/p/astro-guide,/en/p/astro-guide
In Ghost Admin, create a new post:
- Write your article content in Chinese
- Open the Post settings panel (gear icon)
- Scroll down to Tags section
- Add these tags:
#lang-zh(language tag - note the#prefix!)#i18n-astro-guide(translation group tag)type-article(optional: post type)category-tech(optional: category)
- Publish the post
Create a new, separate post in Ghost:
- Write your article content in Japanese
- Add these tags:
#lang-ja← Different language#i18n-astro-guide← Same translation key!type-article,category-tech(same as Chinese version)
- Publish the post
Create another new, separate post in Ghost:
- Write your article content in English
- Add these tags:
#lang-en← Different language#i18n-astro-guide← Same translation key!type-article,category-tech(same as other versions)
- Publish the post
Now you have 3 separate posts in Ghost, all linked by #i18n-astro-guide:
- Chinese post → accessible at
/zh/p/astro-guide - Japanese post → accessible at
/ja/p/astro-guide - English post → accessible at
/en/p/astro-guide
Users can switch between versions using the language switcher on the article page.
| Post Title | Tags |
|---|---|
| "Astro 入门指南" (Chinese) | #lang-zh, #i18n-astro-guide, type-article, category-tech |
| "Astro入門ガイド" (Japanese) | #lang-ja, #i18n-astro-guide, type-article, category-tech |
| "Getting Started with Astro" (English) | #lang-en, #i18n-astro-guide, type-article, category-tech |
- If a language version doesn't exist, the default language (Chinese) is shown
- A notice banner appears indicating the fallback
- Language switcher shows available/unavailable versions
See docs/DEVELOPMENT.md for:
- 🔧 Tech Stack & Project Structure
- 🧞 Available Commands
- 📋 Testing Guide (Unit & Integration)
- 🏗️ Architecture & Code Reference
This project is open source and available under the MIT License.



