Skip to content
Refac7Public

About

A modern, configurable, and self-hostable content platform built with Astro, React, Tailwind CSS, and TypeScript.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Repository files navigation

RefactX

English | 简体中文

A modern, configurable, and self-hostable content platform built with Astro, React, Tailwind CSS, and TypeScript.

RefactX provides a structured foundation for publishing long-form content, maintaining project and link data, and managing content through an integrated CMS. The project combines a cold-paper blue editorial interface, mobile-focused navigation, and a component-oriented architecture intended for individual developers, technical writers, and content-focused personal websites.

Technology Stack

  • Astro 6 — application framework, routing, and static generation
  • React 19 — interactive interfaces such as the administration panel
  • TypeScript — static typing and application contracts
  • Tailwind CSS 4 — styling and design tokens
  • Nano Stores — lightweight client-side state management
  • Vercel Serverless APIs — authentication and CMS operations
  • Pagefind — production-only site search
  • Waline — comments and message board
  • Notion API — dynamic feed synchronization
  • GitHub API (Octokit) — repository-backed content management

Features

  • Markdown-based article publishing with typed content collections
  • Configurable post layouts, pagination, tags, authors, and featured content
  • Integrated CMS for creating, editing, and deleting repository-backed content
  • Support for structured JSON data, including projects, friends, and about-page content
  • Multi-user administration with bcrypt password hashing and JWT-based authentication
  • Repository-backed publishing through the GitHub API
  • Author ownership validation for editorial content
  • Configurable site metadata, navigation, social links, comments, and page content
  • Light and dark themes, seasonal themes, and optional visual effects
  • GitHub contribution activity display
  • Skills showcase and build information sections on the homepage
  • Pagefind site search (available in production builds only)
  • RSS, sitemap, robots.txt, and SEO metadata
  • Editorial design system with poster heroes, glass stats strips, ink surfaces, and numbered sections
  • Mobile side-sheet navigation with a full-height overlay
  • Cover-story homepage feed with a compact latest-articles index
  • Reading progress bar and numbered article headings
  • Responsive layouts designed for desktop and mobile environments
  • Vercel deployment support

Requirements

Dependency Requirement
Node.js 22.12 or later
pnpm 7.1 or later
Git Any supported version

Astro 6 requires Node.js >=22.12.0. Earlier versions may fail to build the project.

Getting Started

Clone the repository and install the dependencies:

git clone https://github.com/Refac7/RefactX.git
cd RefactX
pnpm install

Copy the environment template and fill in the required values:

cp example.env .env

Start the development server:

pnpm dev

By default, the development server is available at http://localhost:4321.

Create a production build:

pnpm build

This command runs type checking, builds the Astro application, and generates the Pagefind search index for .vercel/output/static.

Preview the production build locally:

pnpm preview

Project Structure

RefactX/
├── src/
│   ├── assets/              # Static and application assets
│   ├── components/          # Astro and React components
│   │   ├── admin/           # CMS administration interface
│   │   ├── base/            # Shared components (search, header, contributions, etc.)
│   │   ├── dynamic/         # Dynamic feed components
│   │   ├── posts/           # Post cards, layouts, table of contents, and comments
│   │   │   ├── base/        # Comments, prose wrapper, navigation, tags, and warnings
│   │   │   ├── card/        # PostCard, PostList, and homepage HomeFeed renderers
│   │   │   ├── layouts/     # ArticleLayout, selected through postType
│   │   │   └── toc/         # Table of contents and scroll progress ring
│   │   ├── projects/        # Project presentation components
│   │   ├── theme/           # Theme controls
│   │   └── ui/              # General-purpose UI components
│   ├── content/
│   │   ├── data/            # Structured JSON content
│   │   └── posts/           # Markdown articles
│   ├── layouts/             # Application layouts (Header, Footer, Layout)
│   ├── lib/                 # Utilities, authentication, and rate limiting
│   ├── pages/               # Routes and API endpoints
│   │   └── api/             # Server-side endpoints
│   ├── stores/              # Client-side state
│   ├── styles/              # Design tokens and styling layers
│   │   ├── global.css       # Theme tokens, base rules, dark mode, and reveal utilities
│   │   ├── journal.css      # Editorial layer: heroes, sections, cards, and interaction states
│   │   ├── components.css   # Shared component styles
│   │   └── pro.css          # Long-form prose and markdown media
│   ├── config.ts            # Central site configuration
│   ├── content.config.ts    # Content collection schemas
│   └── types.ts             # Type definitions
├── plugins/                 # Remark and Rehype extensions
├── scripts/                 # Development and administration utilities
├── public/                  # Public static files, hero artwork, and credits
├── astro.config.mjs         # Astro configuration
├── package.json             # Project dependencies and scripts
├── tsconfig.json            # TypeScript configuration
└── vercel.json              # Deployment and cache header configuration

Design System

RefactX uses a cold-paper blue editorial language: large display headings, numbered section headers, hairline rules, poster-style heroes, and inverted ink panels. The mobile layout uses a full-height side-sheet menu that overlays the header when open.

Layer Responsibility
src/styles/global.css Color tokens, typography, base rules, dark mode, reveal and motion utilities
src/styles/journal.css Editorial design layer: page container, section headers, page hero, homepage feed, cards, footer, and interaction states
src/styles/components.css Shared component styles retained for compatibility
src/styles/pro.css Long-form prose, code, tables, callouts, and markdown media

Page Heroes

Page heroes accept an image prop on PageHero. Artwork is stored as 1920×1080 WebP under public/hero-images/, color-graded to the site's slate-blue range, and rendered full-bleed with a vertical journal rail, artwork credit, and a glass statistics strip.

Hero credits are declared in src/lib/heroImages.ts and documented, including page assignments, in public/hero-images/CREDITS.md. When adding or reassigning artwork, update both files.

Mobile Navigation

  • The header menu button opens a full-height side-sheet navigation that covers the page and header.
  • The sheet provides its own close control; search and theme controls remain in the header when it is closed.
  • Background scrolling is locked while the sheet is open; the close button, backdrop click, or Escape dismisses it.

Site Configuration

Primary site configuration is defined in src/config.ts. The configuration module controls site metadata, navigation, social links, post presentation, tag and author pages, project displays, the dynamic feed, message board, friends page, comments, CMS behavior, GitHub integration, and optional seasonal themes.

Typical site metadata:

export const SITE = {
  title: 'RefactX Project',
  description: 'A concise description of the site.',
  website: 'https://example.com',
  base: '/',
  author: 'Author',
  ogImage: '/og-image.webp',
  version: '1.9',
  footerText: 'Footer text',
  footerText2: 'Secondary footer text',
}

Review src/config.ts before deployment and replace the example values with values appropriate for the target site. Commonly used configuration exports include:

Configuration Purpose
SITE Site title, description, domain, author, and OG image
HEADER_LINKS / FOOTER_LINKS Header and footer navigation
SOCIAL_LINKS Social platform links and icons
POSTS_CONFIG Post list density, layout, default cover, and button labels
TAGS_CONFIG / AUTHORS_CONFIG Tag and author page copy
PROJECTS_CONFIG / DYNAMIC_CONFIG Project and dynamic feed page copy
FRIENDS_CONFIG / FRIENDS_CONTACT Friends page and site owner card
WALINE_CONFIG Comment server, CAPTCHA, and image upload settings
CMS_CONFIG CMS toggle, GitHub repository, branch, and path prefix
HOLIDAY_THEMES / HOLIDAY_EFFECTS Holiday theme dates and visual effects
PAGE_LOADER_CONFIG Page transition loading animation

Content Management

Articles

Articles are stored as Markdown files in src/content/posts/. Each article uses YAML frontmatter to define its metadata:

---
title: Article Title
description: A concise summary of the article.
pubDate: 2026-01-01
updatedDate: 2026-01-02
author: Author Name
tags:
  - Astro
  - TypeScript
heroImage: cover.webp
heroImageLayout: right
heroImageAspectRatio: '16/9'
recommend: true
postType: article
contentWarning: Content warning text
---

Field reference:

Field Required Description
title Yes Article title
description Yes Article summary used in listings and SEO
pubDate Yes Publication date
updatedDate No Last updated date
author No Author name; defaults to POSTS_CONFIG.author
tags Yes Array of tags
heroImage No Cover image. Local filenames resolve to /hero-images/; full URLs are used as-is; none disables the image
ogImage No OG image. Local filenames resolve to /og-images/; full URLs are used as-is; none disables the image
heroImageLayout No Cover layout, such as right
heroImageAspectRatio No Cover aspect ratio; defaults to 16/9
recommend No Whether to feature the article; defaults to false
postType No Post layout variant, such as article
contentWarning No Content warning notice

Markdown files beginning with _ are excluded from the content collection and can be used for drafts or partial content.

Markdown Extensions

The rendering pipeline lives in plugins/ and supports:

  • Reading time estimation and low-quality image placeholders (LQIP)
  • Custom directives for badges, links with favicons, and Bilibili embeds
  • Math rendering via remark-math and rehype-katex
  • Callout blocks via rehype-callouts
  • Heading anchors, external link handling, image unwrapping, and table wrappers
  • Expressive Code blocks with collapsible sections and line numbers

Structured Data

Non-article content is stored as JSON under src/content/data/. The friends and projects collections are registered through a custom loader, while about.json is imported directly by the about page:

  • friends.json — friend links
  • projects.json — project information
  • about.json — about-page content

Structured data is not treated as an article and does not require post-specific fields such as author or pubDate.

Example friend entry:

{
  "name": "Site Name",
  "author": "Site Owner",
  "url": "https://example.com",
  "avatar": "https://example.com/avatar.png",
  "description": "A concise description."
}

Example project entry:

{
  "name": "Project Name",
  "description": "A concise project description.",
  "githubUrl": "https://github.com/user/repository",
  "website": "https://example.com",
  "type": "icon",
  "icon": "icon-[mdi--github]",
  "star": 0,
  "fork": 0
}

githubUrl and website are optional; star and fork are required and may be provided as strings or numbers.

Routes

Route Description
/ Homepage with a cover story, latest-articles index, explore cards, contributions, skills, and build information
/posts Paginated post list
/posts/[slug] Individual post
/tags Tag overview
/tags/[tag] Posts filtered by tag
/authors Author overview
/authors/[author] Posts by a specific author
/projects Project showcase
/dynamic Notion-backed dynamic feed with CAPTCHA verification
/messageboard Message board
/friends Friend links
/about About page
/admin CMS administration panel
/api/auth Login and JWT issuance
/api/captcha Proof-of-work CAPTCHA challenge and verification
/api/dynamic Notion dynamic feed proxy
/api/get-content, /api/list-files, /api/batch-commit, /api/next-filename, /api/repo-stats CMS repository operations
/rss.xml RSS feed
/404 Not found page

Server-side endpoints must set export const prerender = false so they run as Vercel Serverless Functions.

CMS Administration

The CMS is configured through CMS_CONFIG and uses a GitHub repository as its content store by default. Authentication supports multiple administrative users through the ADMIN_USERS environment variable.

Generate a password hash with:

# Default username: admin
node scripts/gen-hash.js <password>

# Specify a username
node scripts/gen-hash.js <username> <password>

Add the result to .env:

ADMIN_USERS='{"username":"bcrypt-hash"}'
ADMIN_JWT_SECRET=<secure-random-secret>
CAPTCHA_SECRET=<secure-random-secret>

CMS publishing also requires repository access:

GITHUB_TOKEN=<github-personal-access-token>

The token must have permission to modify the repository and branch configured in CMS_CONFIG. Hashes may also be stored as base64 to avoid dotenv $ variable expansion; the server detects and decodes them automatically.

Authentication flow:

  1. The user enters a username and password.
  2. The client completes a proof-of-work CAPTCHA (SHA-256 difficulty check).
  3. The server verifies the CAPTCHA token, username, and bcrypt password hash.
  4. On success, the server issues a JWT valid for 2 hours; subsequent CMS requests use Authorization: Bearer <token>.
  5. Failed logins are rate-limited (5 failures lock the client IP for 15 minutes by default).

For full authentication, CAPTCHA, and rate-limiting details, see scripts/README.md.

Environment Variables

Copy example.env to .env and fill in the required values.

Variable Required When Purpose
ADMIN_USERS CMS is enabled Administrative users and bcrypt password hashes (JSON)
ADMIN_JWT_SECRET CMS is enabled JWT signing secret
CAPTCHA_SECRET CAPTCHA is enabled CAPTCHA HMAC signing secret
GITHUB_TOKEN CMS publishing is enabled GitHub repository access
NOTION_API_KEY Dynamic feed is enabled Notion API key
NOTION_DATABASE_ID Dynamic feed is enabled Notion database ID
PUBLIC_WALINE_SERVER_URL Comments are enabled Waline server endpoint
PUBLIC_UPLOAD_TOKEN Image upload is enabled Upload service credential
PUBLIC_IMG_BED_URL Image upload is enabled Image hosting endpoint

Generate a random secret with:

openssl rand -hex 32

Variables prefixed with PUBLIC_ are exposed to the client. Never put private credentials in them.

Never commit production credentials, access tokens, or private signing keys to the repository.

Deployment

RefactX uses the @astrojs/vercel adapter by default and can be deployed to Vercel or other environments capable of running the Astro site and its server-side API endpoints.

Vercel

  1. Fork or clone the repository.
  2. Import the project into Vercel.
  3. Configure the required environment variables.
  4. Review src/config.ts, CMS_CONFIG, and the site domain.
  5. Deploy the project.

Use pnpm build as the build command. Static assets are emitted to .vercel/output/static, and the Pagefind index is generated at the end of the build.

vercel.json configures baseline security headers and cache policies:

  • /_astro/* and /fonts/* use one-year immutable caching
  • /pagefind/* uses a one-hour cache with stale-while-revalidate

Comments and External Services

Comment functionality is configured through WALINE_CONFIG and is available on post pages and the message board. Image uploads, Notion synchronization, and other integrations are enabled through public environment variables and site configuration.

External services are deployment dependencies. Their availability, security, and operational configuration are the responsibility of the site operator. Before deploying to production, verify that:

  • The Waline server is deployed and connected to a database
  • The Notion integration has access to the target database
  • The image upload token and endpoint are valid
  • The GitHub token uses the minimum required permissions

Theming

RefactX supports application-wide theme configuration, including light and dark modes. Optional date-based themes and seasonal effects can be configured through HOLIDAY_THEMES and HOLIDAY_EFFECTS.

The page transition loading animation is controlled by PAGE_LOADER_CONFIG and can be disabled for a simpler browsing experience.

Theme-related styles are split between src/styles/global.css (tokens and base theme) and src/styles/journal.css (editorial layer). Hero artwork and page assignments are documented in public/hero-images/CREDITS.md, and the holiday component is located at src/components/base/HolidayTheme.astro.

Development

Before submitting changes, ensure that the project builds successfully:

pnpm build

Other common commands:

pnpm dev           # Start the development server
pnpm format        # Check formatting with Prettier
pnpm format:write  # Automatically fix formatting

Development guidelines:

  • Preserve the existing TypeScript contracts, content schemas, authentication boundaries, and repository-backed CMS behavior.
  • Distinguish editorial posts from structured data. Post-specific validation must not be applied to JSON configuration or data entries that do not use article metadata.
  • Pagefind search loads only when import.meta.env.PROD is true and is unavailable in development mode.
  • React components are used as Astro islands; choose client:load, client:visible, or another hydration directive as appropriate.
  • Inline scripts that rely on is:inline (such as theme initialization) are emitted before bundling; take care when modifying them.
  • Content collections use Astro's loader-based API rather than the legacy src/content/config.ts pattern.
  • Extend the editorial layer in src/styles/journal.css and reuse existing design tokens instead of introducing isolated colors or radii.
  • Preserve the reveal contract (.reveal-enabled + .is-revealed) and prefers-reduced-motion behavior when adding new surfaces.
  • Add every new hero artwork to both src/lib/heroImages.ts and public/hero-images/CREDITS.md.

Contributing

Contributions are welcome through issues and pull requests. Please keep changes focused, document behavior that affects configuration or deployment, and verify the production build before submitting a pull request.

For substantial changes, opening an issue before implementation is recommended so that the proposed approach can be discussed.

License

This project is distributed under the MIT License. See the repository license file for details.

Disclaimer

RefactX is provided on an "AS IS" basis, without warranties or guarantees of any kind, express or implied. The repository maintainer is not obligated to provide continuous maintenance, support, or compatibility updates.

Operators are responsible for reviewing configuration, credentials, third-party integrations, and deployment security before using the project in production.

About

A modern, configurable, and self-hostable content platform built with Astro, React, Tailwind CSS, and TypeScript.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages