English | 简体中文
A clean, elegant, and robust Hexo theme inspired by whitespace (余白). Built with Nunjucks and Tailwind CSS.
Made by Acris with ❤️
- Clean Aesthetics: Minimalist design with focus on typography and readability.
- Responsive: Fully responsive design for mobile and desktop.
- Tailwind CSS: Modern utility-first CSS framework.
- Multi-language: Supports English, Simplified Chinese (
zh-CN), Traditional Chinese (zh-TW), Japanese (ja-JP), and French (fr). - Dark Mode: Elegant dark theme with warm neutral tones, 3-state toggle (system/light/dark).
- Table of Contents: Auto-generated sidebar TOC for articles with configurable heading depth.
- Reading Progress Bar: Thin vermilion progress bar at the top of the page.
- Back to Top: Smooth scroll back-to-top button.
- Code Blocks: Syntax highlighting with copy button and language labels.
- Image Lightbox: Click to zoom images in articles via LightGallery.
- Comments: Disqus (lazy-loaded via
IntersectionObserver) and giscus (GitHub Discussions) comment systems. - Google Analytics: GA4 support with non-blocking script loading.
- RSS: Atom feed support (requires hexo-generator-feed).
- Seal Stamp: Optional decorative vermilion seal (印章) icon in the header, with customizable character via
seal_text. - Static Site Search: Built-in static site search powered by Pagefind — index is generated automatically after
hexo generate, no external service required. - Fast: Optimized for performance with minimal JavaScript.
If you're using Hexo 5.0 or later, the simplest way to install is through npm:
npm i hexo-theme-shiroInstall via git:
git clone -b main --depth=1 https://github.com/Acris/hexo-theme-shiro.git themes/shiroIf you would like to enable RSS, install the feed plugin:
npm i hexo-generator-feedModify theme setting in _config.yml to shiro:
_config.yml
- theme: some-theme
+ theme: shiroTo update your theme to the latest version, use the method matching your installation:
npm
npm i hexo-theme-shiro@latestGit
cd themes/shiro
git pullNote: After upgrading, review the default
_config.ymlfor any new or changed options, and update your_config.shiro.ymlaccordingly.
Create a dedicated theme config file _config.shiro.yml in your site root (Supported since Hexo 5.0.0). This file will
have higher priority than the theme's default config.
Copy the content from themes/shiro/_config.yml to _config.shiro.yml in your site root:
# Site
site:
favicon: /favicon.svg
# Year the site was created; displayed in footer as "since–current" (omit to show current year only)
# since: 2020
# Whether to display the seal (stamp) in the header
seal: true
# Text displayed inside the seal stamp and favicon (single character recommended)
seal_text: "白"
rss:
enabled: false
path: /atom.xml
# Navigation menu
# The "name" field accepts any text — use your preferred language.
# Examples: "Home" (English), "首页" (Chinese), "ホーム" (Japanese)
menu:
- name: Home
url: /
- name: Archives
url: /archives
- name: Categories
url: /categories
- name: Tags
url: /tags
# - name: About
# url: /about
# - name: GitHub
# url: https://github.com/Acris/hexo-theme-shiro
# # Open in new tab
# target: _blank
# Excerpt settings
# Priority: <!-- more --> tag > auto-truncation (when fallback.enabled: true) > full content.
excerpt:
# If post has <!-- more -->, use it.
# Otherwise fallback to auto-truncated excerpt.
fallback:
enabled: true
# Number of characters to truncate (not words)
length: 200
# Table of Contents (TOC)
toc:
enabled: true
# Max heading depth: 2 = h2, 3 = h2+h3, 4 = h2+h3+h4
depth: 3
# Minimum number of headings to show TOC
min_headings: 3
# Dark mode
# Default theme: system (follow OS), light, or dark
# When default is "system", the toggle cycles through 3 states: system → light → dark.
# When default is "light" or "dark", the toggle switches between light ↔ dark only (no system option).
# When toggle is false, the theme toggle button is hidden and the default theme is always used.
# If toggle is disabled, it is recommended to set default to "light" to match the theme's design.
dark_mode:
default: light
toggle: true
# Reading progress bar (thin vermilion bar at top of page)
progress_bar:
enabled: true
# Back to top button
back_to_top:
enabled: true
# Comment systems
# Supported providers: disqus, giscus
# Set enabled to true and choose a provider.
#
# Disqus: register at https://disqus.com/admin/create/ and note the
# unique shortname assigned to your site (e.g., "my-blog-name").
#
# giscus: a comment system powered by GitHub Discussions.
# Go to https://giscus.app/ to generate your configuration values.
# Make sure your repository is public and has Discussions enabled.
comments:
enabled: false
# disqus or giscus
provider: giscus
disqus:
shortname: ""
giscus:
# giscus script URL (self-hosted or default)
src: https://giscus.app/client.js
# GitHub repo (e.g., "owner/repo")
repo: ""
# Repository ID from https://giscus.app
repo_id: ""
# Discussion category name (e.g., "Announcements")
category: ""
# Category ID from https://giscus.app
category_id: ""
# pathname, url, title, og:title, specific, number
mapping: pathname
# 1 to enable strict title matching
strict: 0
# 1 to enable reactions
reactions_enabled: 1
# 1 to emit discussion metadata
emit_metadata: 0
# bottom or top
input_position: bottom
# Language code (e.g., en, zh-CN, ja)
lang: en
# giscus theme CSS URL or built-in theme name (e.g., light, dark, preferred_color_scheme)
# Default uses the bundled Shiro custom theme via jsDelivr CDN.
theme: https://cdn.jsdelivr.net/npm/hexo-theme-shiro@1.3.2/source/css/giscus.css
# true to enable lazy loading (adds data-loading="lazy")
lazy_loading: false
# Analytics
# Currently supports Google Analytics 4 (GA4).
# To get a GA4 Measurement ID, go to https://analytics.google.com/,
# create a property, then find the ID (format: G-XXXXXXXXXX) under
# Admin > Data Streams > Web > Measurement ID.
analytics:
google:
enabled: false
# e.g., "G-XXXXXXXXXX"
id: ""
# Site search powered by Pagefind (https://pagefind.app/)
# Index is built automatically after `hexo generate` and written to `public/pagefind/`.
# For npm-installed themes the binary is auto-resolved from node_modules; for git-clone
# installs run `npm install pagefind --save-dev` in your site root, or rely on the
# `npx --yes pagefind` fallback (requires network on first run).
search:
enabled: false
# Force language for tokenization (auto-detected from <html lang> by default).
# Override only if Pagefind fails to detect your site language correctly.
# force_language: zhSince Hexo does not generate 'all tags' or 'all categories' pages by default, you need to create them manually if you wish to use them in the menu.
-
Create the pages:
hexo new page tags hexo new page categories
-
Modify
source/tags/index.md:--- title: Tags layout: tag ---
-
Modify
source/categories/index.md:--- title: Categories layout: category ---
Shiro ships with a built-in static site search powered by Pagefind. The index is generated automatically right after hexo generate (and therefore also after hexo deploy), so you do not need to run any extra command.
npm install (recommended)
When you install the theme via npm i hexo-theme-shiro, Pagefind is resolved from your site's node_modules if present, otherwise the build hook falls back to npx --yes pagefind, which downloads the binary on first run (network required once).
git clone install
If you cloned the theme into themes/shiro/, install Pagefind once in your site root (not the theme directory):
npm install pagefind --save-devAfter that hexo g will pick it up automatically.
Configuration (_config.yml / _config.shiro.yml)
search:
enabled: true
# Force language for tokenization (auto-detected from <html lang> by default).
# Override only if Pagefind fails to detect your site language correctly.
# force_language: zhSet search.enabled: false to disable the feature: the build hook is skipped and the search button is not rendered.
Local preview
The hook runs on Hexo's before_exit event, scoped to the generate (g) and deploy (d) commands — this guarantees public/ has already been written to disk before Pagefind scans it. hexo server renders pages from memory and does not trigger this hook, so the search index is not rebuilt during local preview. To preview search locally, run a real build and serve the output:
hexo clean && hexo g
npx serve publicIf you want to modify the theme source code or contribute:
hexo-theme-shiro/
├── layout/ # Nunjucks templates
│ ├── _layout.njk # Base layout
│ ├── _macro/ # Reusable macros (ui, archive)
│ ├── _partial/ # Partials (head, header, footer, components, comments, analytics)
│ ├── index.njk # Home page
│ ├── post.njk # Article page
│ ├── page.njk # Standalone page
│ ├── archive.njk # Archive page
│ ├── tag.njk # Tag page
│ └── category.njk # Category page
├── scripts/
│ └── helpers.js # Custom Hexo helpers and generators (clean_description, og_image, favicon_svg, etc.)
├── source/
│ ├── css/_tailwind.css # Tailwind CSS source (compiled to style.min.css)
│ └── js/ # Client-side scripts
├── languages/ # i18n YAML files (en, zh-CN, zh-TW, ja, fr, etc.)
├── _config.yml # Theme default config
└── package.json
-
Install dependencies in the theme directory:
cd themes/shiro npm install -
Watch for CSS changes during development:
npm run dev
-
Build CSS (Tailwind) for production:
npm run build
Note: After modifying _tailwind.css, you must run npm run build to regenerate style.min.css.
- Create a new YAML file in
languages/(e.g.,ko.yml). - Copy the structure from
languages/en.ymland translate all values. - Ensure all top-level keys (
back_to_top,clipboard_copy,clipboard_copied,empty,gallery_view_image,gallery_visit_source,index,nav,page,theme,toc) are present.
Thanks to JetBrains for providing open source licenses.
