Hexo — this supremely cool way for programmers to write — I love it. Even the name “Hexo” sounds like “hacker-o”! If you’re as torn as I am about where to blog, come join us on GitHub and let’s hexo! I’m sure Hexo will catch on quickly.
Hexo was created by Taiwanese university student @tommy351. It’s a static blog framework based on Node.js that can compile hundreds of posts in mere seconds. The static pages Hexo generates can be deployed directly to GitHub Pages, BAE, SAE, and other platforms. First, let’s see how tommy vented about Octopress — Hexo Makes Its Grand Entrance.
The setup process may feel a tad tedious, but once it’s done, writing articles is extremely simple and comfortable.
With just a few simple commands, you can handle everything.
hexo n #new post
hexo g #generate
hexo d #deploy # can be combined with hexo g as: hexo d -g
Let’s dive into the details.
Environment Setup
Install Node
Go to the Node.js website and download the latest version for your platform. Installation is straightforward.
Install Git
There are many Git clients available. Just download from the official site. For detailed instructions, check this article: Building an Independent Blog with GitHub Pages
Install Sublime (Optional)
Sublime Text is used here simply as a text editor. It supports all kinds of programming languages and file formats, including Markdown syntax — a truly exceptional coding companion.
Using GitHub
- First, register a GitHub account (skip if you already have one)
- Create a repository matching your username: “your_user_name.github.com”
- Add your SSH public key at “Account settings -> SSH Keys -> Add SSH Key”
Skipping the first two steps, let’s focus on step three: adding the SSH key.
First, set your username and email:
git config --global user.email "your email"
git config --global user.name "your username"
Generate the key:
ssh-keygen -t rsa -C "your email"
# Enter file path:
H:\hexo\blog>ssh-keygen -t rsa -C "xxxxx@xxxx.com (your email)"
Generating public/private rsa key pair.
Enter file in which to save the key (//.ssh/id_rsa): H:\git\myssh\ssh
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in H:\git\myssh\ssh.
Your public key has been saved in H:\git\myssh\ssh.pub.
The key fingerprint is:
b0:0c:2e:67:33:ab:c1:50:10:40:0a:ba:c1:80:59:22 xiaowu@aips.me
Note: there’s a bug where the drive letter H in the file path must be uppercase, otherwise you’ll get an error. If the above commands succeed, two files — id_rsa and id_rsa.pub — will be generated in H:\git\myssh. The final two steps:
- Open
ssh.pubwith a text editor, copy the contents, and add them at Add SSH Key - Copy
id_rsaandid_rsa.pubto the.sshdirectory under your Git installation, e.g.,H:\PortableGit-1.8.4\.ssh
Verify with:
ssh -T git@github.com
If there are issues, reconfigure. Common errors can be found at:
GitHub Help - Generating SSH Keys
GitHub Help - Error Permission denied (publickey)
Install Hexo
With Node and Git installed, run the following to install Hexo:
npm install -g hexo
Initialization
Run the init command to initialize Hexo in your target directory:
hexo init
You can also cd into the target directory and run hexo init. And that’s it — installation is complete.
Generate Static Pages
Navigate to your init directory and run the following to generate static pages into the hexo\public\ directory:
hexo generate
Note: The command must be run in the init directory. It won’t work otherwise, but it also won’t show any errors.
If modifying article tags or content doesn’t regenerate correctly, try deleting hexo\db.json and retrying. If that doesn’t work, delete the corresponding files in the public directory and regenerate.
Local Preview
Run the following to start a local server for previewing and debugging:
hexo server
Open http://localhost:4000 in your browser to see your Hexo blog.
Writing Articles
Run the new command to create an article at hexo\source\_posts\postName.md. The simplest way is to just create a new Markdown file directly in the Hexo local directory.
hexo new [layout] "postName" #new article
The layout parameter is optional, defaulting to post. Check the scaffolds directory for available layouts — filenames are layout names. You can add your own layouts by creating new files. You can also edit existing layouts, like the post layout at hexo\scaffolds\post.md:
title: {{ title }}
date: {{ date }}
tags:
---
To add categories automatically, just modify this file to add a line:
title: {{ title }}
date: {{ date }}
categories:
tags:
---
The postName is both the md filename and part of the article URL. If it contains spaces, wrap it in quotes. Chinese characters are supported.
Note: All fields must have a space after the colon, otherwise you’ll get errors.
Here’s what the generated file hexo\source\_posts\postName.md looks like:
title: postName #Display name on the article page, freely editable, won't appear in URL
date: 2014-05-16 15:30:16 #Generation time, usually unchanged but editable
categories: #Article category, can be empty. Note: space after the colon
tags: #Article tags, can be empty. For multiple tags use [tag1,tag2,tag3]. Note: space after colon
---
Start writing your content in markdown here.
Now you can write your articles in your favorite editor. For Markdown syntax, refer to the Markdown Syntax Guide.
fancybox
You might be interested in the fancybox effect on the Reading page. Just add a photos field to your article’s .md header and list the photos line by line:
layout: photo
title: My Reading Journey
date: 2085-01-16 07:33:44
tags: [hexo]
photos:
- http://cdn.imzl.com/2013/11/27/reading/photos-0.jpg
- http://cdn.imzl.com/2013/11/27/reading/photos-1.jpg
Don’t want to add this manually each time? Open hexo\scaffolds\photo.md:
layout: { { layout } }
title: { { title } }
date: { { date } }
tags:
photos:
-
---
Then generate photo articles with the layout parameter:
hexo new photo "photoPostName" #new photo article
description
You can also add a description field in the Markdown header to override the global description in _config.yml:
title: hexo your blog
date: 2013-11-22 17:11:54
categories: default
tags: [hexo]
description: Your description for this page
---
Hexo processes all Markdown and HTML files by default. To exclude a file, add layout: false to the header.
Article Excerpts
Add the following where you want the excerpt to end:
Above is the excerpt
<!--more-->
Below is the full text
Content above “more” shows as the excerpt on the homepage. Content below only appears when clicking “Read More.”
Note: All files in Hexo use UTF-8 encoding.
Theme Installation
Everyone has their own taste — swapping themes is a blogging essential. Check out the Hexo Themes list.
My favorites are pacman, modernist, ishgo, and raytaylorism. Pacman is the most polished — clean, fresh, with great mobile support. However, the author didn’t expose many configurable parameters. I ultimately chose modernist.
Install themes with a single git command:
git clone https://github.com/heroicyang/hexo-theme-modernist.git themes/modernist
The directory name doesn’t matter as long as it matches _config.yml.
After installation, open hexo\_config.yml and set the theme to modernist:
theme: modernist
Open hexo\themes\modernist and edit the theme config _config.yml:
menu: #Configure which menus appear in the header
# Home: /
Archives: /archives
Reading: /reading
About: /about
# Guestbook: /about
excerpt_link: Read More #Excerpt link text
archive_yearly: false #Archive by year
widgets: #Configure footer widgets
- category
# - tag
- tagcloud
- recent_posts
# - blogroll
blogrolls: #Blogroll links
- bruce sha's duapp wordpress: http://ibruce.duapp.com
- bruce sha's javaeye: http://buru.iteye.com
- bruce sha's oschina blog: http://my.oschina.net/buru
- bruce sha's baidu space: http://hi.baidu.com/iburu
fancybox: true #Enable fancybox effect
duoshuo_shortname: buru #Duoshuo account
google_analytics:
rss:
Update the theme:
cd themes/modernist
git pull
Comment System
Static blogs need third-party comment systems. Hexo comes with Disqus integration by default, but for well-known reasons, Duoshuo is recommended for Chinese users.
Log into Duoshuo using your Weibo/Douban/Renren/Baidu/Kaixin account and configure the basics. With the modernist theme, set duoshuo_shortname in modernist_config.yml to your Duoshuo shortname. You can also customize the comment box format in Duoshuo’s backend. For CSS settings, refer to this. My setup is based on HeroicYang’s with modifications.
For other third-party comment systems, paste the universal code into hexo/themes/modernist/layout/_partial/comment.ejs:
<% if (config.disqus_shortname && page.comments){ %>
<section id="comment">#Your universal code here
<% } %>
Custom Pages
Run the new page command:
hexo new page "about"
An about directory will be created in hexo\source\ containing index.md. Edit it directly, then configure it to display in the theme’s _config.yml.
This can also be done manually — creating about.md and index.md in hexo\source\ works identically.
Since Markdown doesn’t handle tables well, I build my about page with index.html directly, writing HTML content. Hexo adds the header and footer automatically.
404 Page
GitHub Pages makes custom 404 pages very easy — just create a 404.html in the root directory. However, custom 404 pages only work with custom top-level domains bound to the project. GitHub’s default subdomain and hexo server local debugging won’t trigger them.
Your 404 page can serve a greater purpose — consider a public welfare 404 project. Current charity 404 integration URLs include (I chose Tencent’s):
- Tencent Public Welfare 404
- 404 Public Welfare - Yiyun Social Innovation Center
- Missing Children Center 404
Image Hosting
For blog speed and easier migration, image hosting is essential. I strongly recommend Qiniu Cloud Storage — blazing fast access with logging, hotlink protection, and watermarks.
The free tier includes 10GB monthly traffic + 10GB total space + 100K PUT/DELETE requests + 1M GET requests per month — more than enough for a personal blog. Qiniu doesn’t have directories, but filenames can contain /, e.g., 2013/11/27/reading/photos-0.jpg. See About Key-Value Storage Systems.
If you’re not happy with Qiniu’s web file management interface, try the official Qiniu Cloud Storage Tools.
Custom Domain (Optional)
GitHub Pages assigns each user a subdomain: your_user_name.github.com or your_user_name.github.io — details here.
If that doesn’t satisfy you, register your own domain and bind it to GitHub Pages. Binding is simple: create a CNAME file in the repo root containing just your domain name.
Commands
Common commands:
hexo new "postName" #New article
hexo new page "pageName" #New page
hexo generate #Generate static pages to public directory
hexo server #Start preview server (default port 4000, 'ctrl + c' to stop)
hexo deploy #Deploy .deploy directory to GitHub
Common compound commands:
hexo deploy -g
hexo server -g
Shorthand:
hexo n == hexo new
hexo g == hexo generate
hexo s == hexo server
hexo d == hexo deploy
That covers the basics. Now go write!