Notes to set up a Hexo blog site, as a reminder for the future me. 😁
Setup Node JS
Install the node package manager (npm) if you want to preview/build the website on the local machine.
Windows: Download and install from the official website .
MacOS / Linux: nvm is recommended to install and manage your local version(s) of npm.
The easy way: copy my template site
This template includes these features:
Hexo static site generator.
Fast and elegant Next theme .
markdown-it renderer and KaTeX math.
GitHub actions and GitLab CI included.
Hosting on GitHub: click use as template
to copy this template under your GitHub account.
Hosting on GitLab: import this repo.
In _config.yml
, change baseurl
and your personal settings.
_config.yml 1 2 url: https://username.github.io root: /repo-name/
Also see Hexo configuration for more details.
In _config.next.yml
, change the settings of the Next theme. Also see Next theme settings for further customizations.
The self-serving way
Also checkout getting started in Hexo Next .
Hexo website and and Next theme
install the hexo
command:
setup Next
theme:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 hexo init blog cd blognpm install npm install hexo-theme-next cp ./node_modules/hexo-theme-next/_config.yml _config.next.ymlrm -rf ./themes/landscape
use Next
theme in the config
_config.yml
preview your setup.
1 2 3 4 hexo clean && hexo server -o --debug
You can start blogging using the hexo new
command e.g. hexo new post hello
or start to customize your settings. Press Ctrl + C to exit preview.
Browser sync
By default, you need to press the refresh button when you make a change to the markdown file, which is tedious.
The hexo-browsersync
package comes to the rescue. It issues browser refresh automatically upon filesystem changes in your website in server
mode.
1 npm i hexo-browsersync -D
Useful hexo plugins
1 2 3 4 5 6 7 8 npm i hexo-word-counter npm i hexo-generator-searchdb npm i hexo-filter-emoji
Switch to a better renderer
The default renderer hexo-renderer-marked
does not fully support LaTeX math syntax. Thus, we could switch to a better one.
See the math rendering post to switch the renderer and setup the math typesetting libraries.
Additional markdown-it settings
Install some other useful plugins:
1 npm i markdown-it-imsize markdown-it-named-headings markdown-it-task-checkbox markdown-it-kbd
Add the settings of hexo-renderer-markdown-it
in _config.yml
like this:
_config.yml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 markdown: render: html: true xhtmlOut: false breaks: true linkify: true typographer: false quotes: '' plugins: - markdown-it-abbr - markdown-it-deflist - markdown-it-footnote - markdown-it-latex2img - markdown-it-mark - markdown-it-task-checkbox - markdown-it-kbd - name: markdown-it-emoji options: shortcuts: {} anchors: level: 2 collisionSuffix: 'v' permalink: true permalinkClass: header-anchor permalinkSide: 'left' permalinkSymbol: "" case: 1 separator: '-'
Deployment
Create a file .github/workflows/gh-pages.yml
for GitHub actions.
Also see GitHub action for GitHub pages
With pandoc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 name: github pages env: NODE_ENV: production PDC_VER: "2.17.1.1" on: push: branches: - main jobs: build: name: Build website runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Restore last modified time run: "git ls-files -z | while read -d '' path; do touch -d \"$(git log -1 --format=\"@%ct\" \"$path\")\" \"$path\"; done" - uses: actions/setup-node@v2.1.4 with: node-version: '14' - name: Cache Dependencies uses: actions/cache@v2 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node- - name: Setup Pandoc run: wget -qO- https://github.com/jgm/pandoc/releases/download/${PDC_VER}/pandoc-${PDC_VER}-linux-amd64.tar.gz | sudo tar xvz --strip-components 1 -C /usr/local - name: Build website run: npm ci && npm run build - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: personal_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./public full_commit_message: ${{ github.event.head_commit.message }}
With markdown-it
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 name: github pages env: NODE_ENV: production on: push: branches: - main jobs: build: name: Build website runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Restore last modified time run: "git ls-files -z | while read -d '' path; do touch -d \"$(git log -1 --format=\"@%ct\" \"$path\")\" \"$path\"; done" - uses: actions/setup-node@v2.1.4 with: node-version: '14' - name: Cache Dependencies uses: actions/cache@v2 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node- - name: Build website run: npm ci && npm run build - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: personal_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./public full_commit_message: ${{ github.event.head_commit.message }}
Create a file .gitlab-ci.yml
for GitLab CI/CD. Also see the documentation of GitLab pages.
With pandoc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 image: tarampampam/node:lts-alpine cache: key: ${CI_COMMIT_REF_SLUG} paths: - .npm/ variables: NODE_ENV: "production" PDC_VER: "2.11.3.1" before_script: - "git ls-files -z | while read -d '' path; do touch -d \"$(git log -1 --format=\"@%ct\" \"$path\")\" \"$path\"; done" - "wget -qO- https://github.com/jgm/pandoc/releases/download/${PDC_VER}/pandoc-${PDC_VER}-linux-amd64.tar.gz | tar xvz --strip-components 1 -C /usr/local" - npm ci --cache .npm --prefer-offline - npm run build test: stage: test script: - echo "Done" except: - main pages: stage: build script: - apk add --update brotli - find public -type f -regex '.*\.\(htm\|html\|txt\|text\|js\|css\|svg\|xml\)$' -exec gzip -f -k {} \; || echo 'Gzip failed. Skipping...' - find public -type f -regex '.*\.\(htm\|html\|txt\|text\|js\|css\|svg\|xml\)$' -exec brotli -f -k {} \; || echo 'Brotli failed. Skipping...' artifacts: paths: - public only: - main
With markdown-it
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 image: tarampampam/node:lts-alpine cache: key: ${CI_COMMIT_REF_SLUG} paths: - .npm/ variables: NODE_ENV: "production" before_script: - "git ls-files -z | while read -d '' path; do touch -d \"$(git log -1 --format=\"@%ct\" \"$path\")\" \"$path\"; done" - npm ci --cache .npm --prefer-offline - npm run build test: stage: test script: - echo "Done" except: - main pages: stage: build script: - apk add --update brotli - find public -type f -regex '.*\.\(htm\|html\|txt\|text\|js\|css\|svg\|xml\)$' -exec gzip -f -k {} \; || echo 'Gzip failed. Skipping...' - find public -type f -regex '.*\.\(htm\|html\|txt\|text\|js\|css\|svg\|xml\)$' -exec brotli -f -k {} \; || echo 'Brotli failed. Skipping...' artifacts: paths: - public only: - main