Skip to content

A modern, high-performance personal blog interface built with Astro + React + TailwindCSS, powered by Ghost CMS as headless backend. Features multi-language support (zh/ja/en), dark/light themes, and multiple post types.

License

Notifications You must be signed in to change notification settings

SolitudeRA/Solitude-Interface

Repository files navigation

Solitude Interface

thumbnail

Node.js pnpm Astro License

A modern personal blog interface built with Astro and powered by Ghost CMS API.

Read this in: English | 简体中文 | 日本語


📑 Table of Contents


🚀 Features

  • 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)

📸 Screenshots

Click to expand screenshots

Home

Home

Post

Post

About Me

About-Me

Post Detail

Post-Detail


📖 Documentation

Document Description
README.md (this file) User guide - setup and content publishing
DEVELOPMENT.md Developer guide - architecture, testing, workflows, and contributing

🚀 Quick Start

1. Install Dependencies

This project uses pnpm.

# (Recommended) Enable pnpm via Corepack
corepack enable pnpm

pnpm install

If corepack is not available on your system, you can install pnpm globally with npm i -g pnpm.

2. Configure Environment

Create a .env file from the template:

cp .env.example .env

Edit .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=

Environment Variables

Required
Variable Description
GHOST_URL Base URL of your Ghost instance
GHOST_CONTENT_KEY Ghost Content API key
SITE_URL Public site URL for canonical and hreflang
Optional
Variable Default Description
GHOST_VERSION v5.0 Ghost Content API version
GHOST_TIMEOUT 5000 Ghost request timeout in milliseconds
IMAGE_HOST_URL - Image host/CDN used for remote image domain allowlist
GOOGLE_ANALYTICS_TAG_ID - Google tag / GA4 Measurement ID (e.g., G-XXXX). Leave empty to disable
CF_ACCESS_CLIENT_ID - Cloudflare Access Service Token Client ID (if Ghost is protected by CF Access)
CF_ACCESS_CLIENT_SECRET - Cloudflare Access Service Token Client Secret

Cloudflare Access Configuration (Optional)

If your Ghost instance is protected by Cloudflare Access, you need to configure Service Tokens to allow API access:

  1. Create a Service Token in your Cloudflare Zero Trust dashboard:

    • Go to AccessService AuthService Tokens
    • Click Create Service Token
    • Copy the Client ID and Client Secret
  2. Add the token to your .env:

    CF_ACCESS_CLIENT_ID=your-client-id.access
    CF_ACCESS_CLIENT_SECRET=your-client-secret
  3. Add a bypass policy in your Access Application:

    • Go to AccessApplications → Your Ghost App
    • Add a policy with Action: Service Auth and select your service token

Note: The API client will automatically include CF-Access-Client-Id and CF-Access-Client-Secret headers when these environment variables are set.

3. Get Your Ghost Content API Key

  1. Log in to your Ghost Admin panel
  2. Navigate to SettingsIntegrations
  3. Click Add custom integration
  4. Copy the Content API Key into your .env file

Tip: Use the Ghost Demo API for testing:

GHOST_URL=https://demo.ghost.io
GHOST_CONTENT_KEY=22444f78447824223cefc48062

4. Start Development Server

pnpm dev

Visit http://localhost:4321 to see your site.


🔧 Common Commands

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

📝 Content Publishing Guide

Classification Tags

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

Supported Post Types

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

🌐 Multi-language Content

URL Structure

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

Required Tags for Multi-language

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 #xxx are converted to slug format hash-xxx.

📘 Step-by-Step Guide: Creating Multi-language Posts

Important: Each language version is a separate post in Ghost. They are linked together using the same #i18n-{key} tag.

Step 1: Plan your translation group key

Choose a unique key for your article, e.g., astro-guide. This key will be used in:

  • The #i18n-astro-guide tag (to link all versions)
  • The URL: /zh/p/astro-guide, /ja/p/astro-guide, /en/p/astro-guide

Step 2: Create the Chinese version

In Ghost Admin, create a new post:

  1. Write your article content in Chinese
  2. Open the Post settings panel (gear icon)
  3. Scroll down to Tags section
  4. 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)
  5. Publish the post

Step 3: Create the Japanese version

Create a new, separate post in Ghost:

  1. Write your article content in Japanese
  2. Add these tags:
    • #lang-ja ← Different language
    • #i18n-astro-guideSame translation key!
    • type-article, category-tech (same as Chinese version)
  3. Publish the post

Step 4: Create the English version

Create another new, separate post in Ghost:

  1. Write your article content in English
  2. Add these tags:
    • #lang-en ← Different language
    • #i18n-astro-guideSame translation key!
    • type-article, category-tech (same as other versions)
  3. Publish the post

Result

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.

Complete Example

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

Fallback Behavior

  • 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

🛠️ For Developers

See docs/DEVELOPMENT.md for:

  • 🔧 Tech Stack & Project Structure
  • 🧞 Available Commands
  • 📋 Testing Guide (Unit & Integration)
  • 🏗️ Architecture & Code Reference

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.


🙏 Acknowledgments

  • Astro - The web framework for content-driven websites
  • Ghost - The professional publishing platform
  • TailwindCSS - A utility-first CSS framework
  • React - The library for web and native user interfaces

📄 License

This project is open source and available under the MIT License.

About

A modern, high-performance personal blog interface built with Astro + React + TailwindCSS, powered by Ghost CMS as headless backend. Features multi-language support (zh/ja/en), dark/light themes, and multiple post types.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •