Welcome to Charlotte
Relevant source files
The following files were used as context for generating this wiki page:- README.md
- src/config.ts
- package.json
- src/content/posts/2018-10-30/Charlotte-Markdown.md
- scripts/new-post.js
- src/types/config.ts
- src/utils/content-utils.ts
- src/plugins/expressive-code/code-toolbar.ts
- src/pages/rss.xml.ts
- src/pages/atom.xml.ts
- frontmatter.json
- src/content/posts/2025-09-29/Unveiling.md
Charlotte is a customizable blog theme built on the Astro framework, serving as the foundation for Chuwu's Blog. It is derived from the Fuwari theme and incorporates a range of modern web technologies to provide a feature-rich, high-performance static site for personal blogging. The project emphasizes ease of content creation, extensive customization through a central configuration file, and a polished user experience with features like a typing-effect banner, theme switching, and extended Markdown syntax.
The technology stack includes Astro for the core architecture, Svelte for interactive UI components, and Tailwind CSS for styling. Content is managed through Markdown files with frontmatter, and the project includes scripts to streamline post creation. It is designed for deployment on static hosting platforms like Netlify and Vercel.
Sources: README.md, src/content/posts/2025-09-29/Unveiling.md, package.json
Getting Started
This section covers the initial setup and common commands for developing with the Charlotte theme.
Environment Requirements
The project requires specific versions of Node.js and pnpm to ensure compatibility.
| Tool | Version Requirement |
|---|---|
| Node.js | >= 22 |
| pnpm | >= 9 |
Sources: README.md:19-21
Development Workflow and Commands
The development process involves installing dependencies, running a local development server, and building the site for production. Key scripts are defined in package.json to automate these tasks.
The following diagram illustrates the typical development and build workflow.
Sources: package.json:5-16, README.md:23-36
A comprehensive list of commands is available for managing the project lifecycle.
| Command | Description |
|---|---|
pnpm install | Install project dependencies. |
pnpm dev | Start the development server after cleaning cache. |
pnpm build | Build the production version and run Pagefind. |
pnpm preview | Preview the production build locally. |
pnpm check | Run Astro's type checker. |
pnpm format | Format code in the ./src directory using Biome. |
pnpm lint | Check and fix code style issues using Biome. |
pnpm new-post <name> | Create a new blog post with a pre-filled template. |
pnpm clean | Clean Astro, Vite, and dist build caches. |
Sources: README.md:23-36, package.json:5-16
Content Management
Content in Charlotte is organized as Markdown files within the src/content/posts/ directory. The system provides tools and conventions for creating and managing posts.
Creating a New Post
A new post can be scaffolded using a dedicated script, which creates a Markdown file with a basic frontmatter structure.
pnpm new-post <filename>
This command executes the scripts/new-post.js script. The script's logic is as follows:
- Parses the provided filename.
- Appends
.mdif no extension is given. - Checks if a file with the same name already exists to prevent overwrites.
- Creates the necessary subdirectories if they don't exist.
- Writes a new file with a frontmatter template containing the title and the current date.
The following flowchart shows the process of the new-post script.
Sources: scripts/new-post.js, README.md:38-42
Post Frontmatter
Each post must contain YAML frontmatter at the top of the Markdown file to define its metadata. This metadata is used to render the post, generate lists, and for SEO.
| Attribute | Type | Description |
|---|---|---|
title | string | The title of the post. |
published | Date | The publication date of the post. |
description | string | A short summary of the post, displayed on the homepage and in meta tags. |
image | string | The path to the post's cover image. Can be a URL, a path relative to /public (starts with /), or a path relative to the Markdown file. |
tags | string[] | A list of tags associated with the post. |
category | string | The category of the post. |
draft | boolean | If true, the post will not be displayed on the production site. |
Sources: src/content/posts/2018-10-30/Charlotte-Markdown.md:11-23, frontmatter.json:19-74
Content Processing and Sorting
Posts are retrieved and processed using utility functions in src/utils/content-utils.ts. The primary function, getSortedPosts, handles fetching, sorting, and ordering posts.
The processing flow is as follows:
- Fetch Posts: All posts are fetched from the
src/content/postscollection using Astro'sgetCollectionAPI. Drafts are excluded in production. - Sort by Date: Posts are sorted in descending order by their
publisheddate. - Apply Pinned Ordering: If enabled, posts listed in
siteConfig.pinnedPostare moved to the top of the list, preserving their configured order. - Add Navigation Links: The
prevSlug/prevTitleandnextSlug/nextTitleproperties are added to each post object for post-to-post navigation.
This diagram illustrates the post retrieval and sorting logic.
Sources: src/utils/content-utils.ts:10-80
Configuration
The blog's behavior and appearance are primarily controlled via the src/config.ts file. This centralizes customization options for easy management. The data structures for these configurations are defined in src/types/config.ts.
Main Site Configuration (siteConfig)
This object contains global settings for the site.
| Property | Type | Description |
|---|---|---|
title | string | The main title of the site. |
subtitle | string | A secondary title or slogan. |
url | string | The base URL of the blog. |
lang | "en" | "zh_CN" | "zh_TW" | "ja" | The primary language of the site. |
themeColor | object | Defines the hue (0-360) for the site's theme and whether the color picker is fixed (hidden). |
defaultTheme | "light" | "dark" | "auto" | The default color mode for new visitors. |
banner | object | Configuration for the homepage banner, including image source, text, and credits. |
toc | object | Enables or disables the Table of Contents on post pages and sets its maximum depth (1-3). |
startDate | string | The start date for the "website runtime" counter in the footer. |
pinnedPost | string | string[] | A list of post slugs to pin to the top of the homepage. |
performance | object | Performance-related settings, such as pre-warming external links. |
Sources: src/config.ts:11-70, src/types/config.ts:3-45
Other Configurations
navBarConfig: Defines the links in the main navigation bar. It accepts presets likeLinkPreset.Homeor custom link objects. You can also set the navbar's opacity.profileConfig: Configures the author profile card, including the avatar, name, bio, and social media links with icons.licenseConfig: Manages the display of a content license (e.g., Creative Commons) at the bottom of posts.expressiveCodeConfig: Sets the theme for code blocks rendered by the Expressive Code plugin.
Sources: src/config.ts:72-117, src/types/config.ts:53-93
Features and Custom Syntax
Charlotte extends standard Markdown with several custom features to enhance content presentation and functionality.
Extended Markdown Syntax
The theme supports special syntax for embedding rich components directly into Markdown files.
| Feature | Syntax | Description |
|---|---|---|
| GitHub Card | ::github{repo="owner/repo"} | Renders a dynamic card with information about a GitHub repository. |
| Admonitions | :::note[Title] ... ::: | Creates styled blocks for notes, tips, warnings, etc. Also supports GitHub syntax > [!NOTE]. |
| Spoilers | Content :spoiler[Hidden text]! | Hides text until the reader clicks on it. |
| Embedded Videos | <iframe ...></iframe> | Allows embedding videos from platforms like YouTube by pasting their HTML embed code. |
Sources: src/content/posts/2018-10-30/Charlotte-Markdown.md:120-200
Code Blocks with Toolbar
Code blocks are enhanced with a custom toolbar using the astro-expressive-code plugin. A custom plugin, pluginCodeToolbar, is used to create a toolbar at the top of each code block.
The toolbar includes:
- Language Badge: Displays the language of the code block.
- Title: An optional title can be displayed in the center, extracted from the code block's meta string (e.g.,
```js title="My Code"). - Copy Button: A button to copy the code to the clipboard, with visual feedback on success.
The following diagram shows how the toolbar is added to a code block during the rendering process.
Syndication Feeds (RSS & Atom)
The project automatically generates both RSS and Atom XML feeds for content syndication. This is handled by endpoint files in src/pages/.
src/pages/rss.xml.ts: Generates the RSS 2.0 feed.src/pages/atom.xml.ts: Generates the Atom 1.0 feed.
Both endpoints follow a similar process:
- Fetch all published posts using
getSortedPosts. - Iterate through each post.
- Render the post's Markdown body to HTML.
- Sanitize the resulting HTML to remove potentially harmful tags, while allowing
<img>. - Construct the XML feed structure with the site's metadata and the processed post items.
- For RSS, relative image URLs are converted to absolute URLs to ensure they render correctly in feed readers.
Sources: src/pages/rss.xml.ts, src/pages/atom.xml.ts