A modern personal blog interface built with Astro and powered by Ghost CMS API. This project is currently under active development.
- High-performance static site built with Astro
- Ghost CMS integration (Headless)
- Multi-language support (zh/ja/en) with automatic fallback
- Responsive design
- Dark/light theme toggle
- Multiple post type displays (articles, gallery, video, music)
- SEO optimized (hreflang, canonical, html lang)
- Comprehensive testing suite (unit + integration tests)
This project is currently in active development. Features and documentation will be expanded as the project matures.
The project follows a modular structure with separate directories for API integration, components, layouts, and pages.
- Astro
- React
- TypeScript
- TailwindCSS
- Ghost Content API
- Vitest - Testing framework
| Command | Action |
|---|---|
npm install |
Install dependencies |
npm run dev |
Start local dev server at localhost:4321 |
npm run build |
Build production site to ./dist/ |
npm run preview |
Preview build locally before deploying |
npm run format |
Format code with Prettier |
npm test |
Run tests in watch mode |
npm run test:unit |
Run unit tests only (fast, with mocks) |
npm run test:integration |
Run integration tests (real API calls) |
npm run test:coverage |
Run tests with coverage report |
npm run test:ui |
Open Vitest UI for interactive testing |
Create a .env file in the root directory. You can use .env.example as a template:
cp .env.example .envEdit the .env file with your Ghost instance information:
# Ghost Content API Configuration
GHOST_URL=https://your-ghost-instance.com
GHOST_CONTENT_KEY=your-content-api-key-here
GHOST_VERSION=v5.0
# Your Site URL
SITE_URL=https://your-site.example.com- Log in to your Ghost Admin panel
- Navigate to Settings โ Integrations
- Click Add custom integration
- Create an integration and copy the Content API Key
- Paste the API key into your
.envfile
Alternative: Use the Ghost Demo API for testing:
GHOST_URL=https://demo.ghost.io
GHOST_CONTENT_KEY=22444f78447824223cefc48062Note: The demo API is read-only and may have rate limits.
This project includes two types of tests:
- Unit Tests: Fast tests using mock data, no external dependencies
- Integration Tests: Tests using real Ghost API to verify actual behavior
# Run all tests
npm test
# Run only unit tests (fast, no API needed)
npm run test:unit
# Run only integration tests (requires .env configuration)
npm run test:integration| Feature | Unit Tests | Integration Tests |
|---|---|---|
| Speed | โก Fast (< 1s) | ๐ Slower (10-30s) |
| Dependencies | โ None | |
| API Calls | โ Mocked | โ Real Ghost API |
| Use Case | Daily development | Pre-commit verification |
| Command | npm run test:unit |
npm run test:integration |
# Watch mode - runs tests on file changes
npm test
# Run all tests once
npm run test:all
# Run unit tests only
npm run test:unit
# Run integration tests only
npm run test:integration
# Generate coverage report
npm run test:coverage
# Open interactive UI
npm run test:ui- Ghost adapter logic (URL transformations, tag extraction)
- Cloudflare Zero Trust adapter
- Cache utilities
- Error handlers
- API client structure
- Real Ghost API connection
- Fetching posts and site information
- Data structure validation
- URL adaptation and transformation
- Tag extraction and categorization
- Cache performance (first call = API, second call = cache)
- Error handling with actual endpoints
src/api/__tests__/
โโโ setup.ts # Unit test setup (mocks env vars)
โโโ setup.integration.ts # Integration test setup (uses real env vars)
โโโ adapters/
โ โโโ ghost.test.ts # Unit: Ghost adapter
โ โโโ cloudflare.test.ts # Unit: Cloudflare adapter
โโโ clients/
โ โโโ ghost.test.ts # Unit: Ghost API client
โ โโโ ghost.integration.test.ts # Integration: Real API calls
โโโ ghost/
โ โโโ posts.test.ts # Unit: Posts API
โ โโโ posts.integration.test.ts # Integration: Real post data
โ โโโ settings.test.ts # Unit: Settings API
โ โโโ settings.integration.test.ts # Integration: Real site info
โโโ utils/
โโโ cache.test.ts # Unit: Cache utilities
โโโ errorHandlers.test.ts # Unit: Error handlers
Naming Convention:
- Unit tests:
*.test.ts - Integration tests:
*.integration.test.ts
This project supports three languages: Chinese (zh), Japanese (ja), and English (en).
| 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 |
For multi-language to work, posts in Ghost must have specific internal tags:
-
Language Tag (required, one of):
#lang-zh- Chinese content#lang-ja- Japanese content#lang-en- English content
-
Translation Group Tag (required):
#i18n-{key}- Links translations together- Example:
#i18n-intro-to-solitude
To create the same article in 3 languages:
| Post Title | Tags |
|---|---|
| "Solitude ็ฎไป" (Chinese) | #lang-zh, #i18n-intro-to-solitude |
| "Solitude ็ดนไป" (Japanese) | #lang-ja, #i18n-intro-to-solitude |
| "Intro to Solitude" (English) | #lang-en, #i18n-intro-to-solitude |
- 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
Default language is set in src/lib/i18n.ts:
export const DEFAULT_LOCALE: Locale = 'zh';To change the default, modify this value and update astro.config.mjs:
i18n: {
locales: ['zh', 'en', 'ja'],
defaultLocale: 'zh', // Change this
}This project is open source and available under the MIT License.