Hugo × Cloudflareで簡単ブログ構築
HugoとCloudflare Pagesを使うと、Markdownで執筆できるBlogを簡単かつ無料で構築できます。
本記事ではStackというテーマを使い、以下のようなブログを作る手順を追っていきます。
前提
環境等は以下です。
- WSL2 (Ubuntu 20.04.2 LTS) 上で作業する
-
wget
やtar
コマンドはインストール済
Goをインストールする
まずはGoをインストールします。
最新版のGoをwgetして
wget https://dl.google.com/go/go1.22.0.linux-amd64.tar.gz
tarで解凍し
sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz
PATHを通します。
export PATH=$PATH:/usr/local/go/bin
go version
バージョンが返ってくればGoのインストールは完了です。
要らなくなった圧縮ファイルは削除しておきます。
rm go1.22.0.linux-amd64.tar.gz
Hugoをインストールする
幾つか方法がありますが、Build from sourceでやっていきます。
CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@latest
packageは ~/go
配下に落ちているのでPATHを新たに追加します。
export PATH=$PATH:~/go/bin
hugo version
バージョンが返ってくればOKです。
Hugoでプロジェクトを作る
コマンド一発で雛形ができます。
以下のコマンドでは blog
ディレクトリが新たに作られ、その中に各種ファイルが生成されます。
hugo new site blog
Themeを追加する
Hugoでは多くのThemeが利用できます。
今回は高機能で見た目もイケてるStackというThemeを採用します。
git initしてthemeをsubmoduleとして追加します。
cd blog
git init
git submodule add git@github.com:CaiJimmy/hugo-theme-stack.git themes/hugo-theme-stack
hugo.toml
へthemeの指定を追記します。
echo "theme = 'hugo-theme-stack'" >> hugo.toml
hugoのserverを起動してみます。
hugo server
Stackが適用されたページが localhost:1313で起動します。
投稿してみる
新しい投稿を作成します。
hugo new content post/hello-world/index.md
Front Matterのdraftはデフォルトでtrueになっているので、公開中の記事を参照するコマンドである hugo server
では見えません。
draftをfalseにする、または
hugo server -D
で下書きも含む全記事を確認しながら執筆できます。
Stack独自のカスタマイズをする
config
hugo.toml
を削除し、公式のexampleSiteの config.yaml
をコピーして編集します。
config.yamlの設定
- baseurlやtitle、copyright、socialのリンク等は適宜書き換えてください
- コメント機能はOFFにしています。ONにしたい場合は
comments
のenabled
をtrue
にし、各種サービスの設定を入れてください - サイドバーのアバターは
assets/img/avatar.jpg
を読み込む設定となっています
baseurl: https://blog.seitaro.work/
languageCode: ja
theme: hugo-theme-stack
paginate: 3
title: Seitaro Blog
copyright: Seitaro
# GA Tracking ID
googleAnalytics:
# Theme i18n support
# Available values: ar, bn, ca, de, el, en, es, fr, hu, id, it, ja, ko, nl, pt-br, th, uk, zh-cn, zh-hk, zh-tw
DefaultContentLanguage: en
# Set hasCJKLanguage to true if DefaultContentLanguage is in [zh-cn ja ko]
# This will make .Summary and .WordCount behave correctly for CJK languages.
hasCJKLanguage: true
permalinks:
post: /p/:slug/
page: /:slug/
params:
mainSections:
- post
featuredImageField: image
rssFullContent: true
favicon: # e.g.: favicon placed in `static/favicon.ico` of your site folder, then set this field to `/favicon.ico` (`/` is necessary)
footer:
since: 2024
customText:
dateFormat:
published: 2006/01/02
lastUpdated: 2006/01/02 15:04 JST
sidebar:
emoji:
subtitle: A software developer based in Japan.
avatar:
enabled: true
local: true
src: img/avatar.jpg
article:
math: true
toc: true
readingTime: true
license:
enabled: false
default: Licensed under CC BY-NC-SA 4.0
comments:
enabled: false
provider: disqus
disqusjs:
shortname:
apiUrl:
apiKey:
admin:
adminLabel:
utterances:
repo:
issueTerm: pathname
label:
remark42:
host:
site:
locale:
vssue:
platform:
owner:
repo:
clientId:
clientSecret:
autoCreateIssue: false
# Waline client configuration see: https://waline.js.org/en/reference/component.html
waline:
serverURL:
lang:
pageview:
emoji:
- https://unpkg.com/@waline/emojis@1.0.1/weibo
requiredMeta:
- name
- email
- url
locale:
admin: Admin
placeholder:
twikoo:
envId:
region:
path:
lang:
# See https://cactus.chat/docs/reference/web-client/#configuration for description of the various options
cactus:
defaultHomeserverUrl: "https://matrix.cactus.chat:8448"
serverName: "cactus.chat"
siteName: "" # You must insert a unique identifier here matching the one you registered (See https://cactus.chat/docs/getting-started/quick-start/#register-your-site)
giscus:
repo:
repoID:
category:
categoryID:
mapping:
lightTheme:
darkTheme:
reactionsEnabled: 1
emitMetadata: 0
gitalk:
owner:
admin:
repo:
clientID:
clientSecret:
cusdis:
host:
id:
widgets:
homepage:
- type: search
- type: archives
params:
limit: 5
- type: categories
params:
limit: 10
- type: tag-cloud
params:
limit: 10
page:
- type: toc
opengraph:
twitter:
# Your Twitter username
site:
# Available values: summary, summary_large_image
card: summary_large_image
defaultImage:
opengraph:
enabled: false
local: false
src:
colorScheme:
# Display toggle
toggle: true
# Available values: auto, light, dark
default: auto
imageProcessing:
cover:
enabled: true
content:
enabled: true
### Custom menu
### See https://docs.stack.jimmycai.com/configuration/custom-menu.html
### To remove about, archive and search page menu item, remove `menu` field from their FrontMatter
menu:
main: []
social:
- identifier: github
name: 01_GitHub
url: https://github.com/seita1996
params:
icon: brand-github
- identifier: twitter
name: 02_Twitter
url: https://twitter.com/seita_1996
params:
icon: brand-twitter
- identifier: rss
name: 03_RSS
url: /index.xml
params:
icon: rss
related:
includeNewer: true
threshold: 60
toLower: false
indices:
- name: tags
weight: 100
- name: categories
weight: 200
markup:
goldmark:
renderer:
## Set to true if you have HTML content inside Markdown
unsafe: true
tableOfContents:
endLevel: 4
ordered: true
startLevel: 2
highlight:
noClasses: false
codeFences: true
guessSyntax: true
lineNoStart: 1
lineNos: true
lineNumbersInTable: true
tabWidth: 4
ページと機能の追加
content
配下には現在 post
ディレクトリしかないので、 about
archives
search
を追加していきます。
about
を追加すると、新規ページが追加され、メニューにリンクが追加されます。
archives
と search
を追加すると、新規ページとメニューへのリンク追加に加え、Stackが用意してくれているアーカイブと検索機能が使えるようになります。
about archives searchページの設定
---
title: About
aliases:
- contact
menu:
main:
weight: -90
params:
icon: user
---
## 自己紹介
- aaa
---
title: "Archives"
date: 2019-05-28
layout: "archives"
slug: "archives"
menu:
main:
weight: -70
params:
icon: archives
---
---
title: "Search"
slug: "search"
layout: "search"
outputs:
- html
- json
menu:
main:
weight: -60
params:
icon: search
---
日本語フォントへの変更
Stackではデフォルトのフォントが中華フォントになっているため、日本語フォントへ変更します。
themes/hugo-theme-stack/assets/scss/variables.scss
に
--zh-font-family: "PingFang SC", "Hiragino Sans GB", "Droid Sans Fallback", "Microsoft YaHei";
--base-font-family: "Lato", var(--sys-font-family), var(--zh-font-family), sans-serif;
--code-font-family: Menlo, Monaco, Consolas, "Courier New", var(--zh-font-family), monospace;
のようにスタイルの記述があるため、一見ここを修正すればよさそうに見えますが、GitのSubmoduleとなっているため直接触るのは悪手です。
HugoがサイトをBuildすると、rootディレクトリとTheme内のディレクトリは統合されるらしい[1]ので、 assets
配下に scss
ディレクトリを作成し、 custom.scss
を新規作成して日本語フォントのスタイルを記述します。
:root {
--sys-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Droid Sans", "Helvetica Neue";
--ja-font-family: "游ゴシック体", "Yu Gothic", YuGothic, "ヒラギノ角ゴ Pro", "Hiragino Kaku Gothic Pro", "メイリオ", "Meiryo";
--base-font-family: "Lato", var(--sys-font-family), var(--ja-font-family), sans-serif;
--code-font-family: Menlo, Monaco, Consolas, "Courier New", var(--ja-font-family), monospace;
}
その他
gitignore
Hugo用のignore設定を使い、gitignoreを作成します。
# Generated files by hugo
/public/
/resources/_gen/
/assets/jsconfig.json
hugo_stats.json
# Executable may be added to repository
hugo.exe
hugo.darwin
hugo.linux
# Temporary lock file while building
/.hugo_build.lock
これにより hugo server
のコマンドで public
配下に生成されるHTML等を追跡対象から外すことができます。
記事のテンプレート
コマンドで記事を生成する際に archetypes/default.md
を設定しておくと、テンプレートとして利用できます。
例えばこのようなFront Matterや見出しをテンプレートとして設定しておくと
---
title: '{{ replace .File.ContentBaseName "-" " " | title }}'
date: {{ .Date }}
draft: true
image: 'sample.jpg'
categories:
- Tech
tags:
- tag
---
## heading
記事の作成コマンド
hugo new content post/hello-world/index.md
を実行したときに
---
title: 'Hello World'
date: 2024-02-20T21:57:43+09:00
draft: false
image: 'sample.JPEG'
categories:
- Tech
tags:
- tag
---
## heading
このような形で雛形を作ってくれます。
画像関連
favicon
を設定したい場合は static
ディレクトリ直下に favicon.ico
を配置します。
特定の記事以外でも使いたいグローバルな画像(アイコンなど)は assets
ディレクトリ配下に置いておくとどこからでも呼び出すことができます。
特定の記事だけで使いたいローカルな画像は記事と同じディレクトリに置いてあげるとよいです。
記事のトップ画像を設定する場合はFront Matterにimage指定してあげればOKです。
OGPは config.yaml
で自動生成するよう設定されています。
Cloudflare Pagesへデプロイする
ここまでで作成したコードや記事は、GitHubまたはGitLabの新規リポジトリにPushしておきます。
Cloudflare を使うと静的ページのホストができます(アクセス数の少ない個人ブログであれば無料で全く問題ありません)
メニューの「Workers & Pages」から「アプリケーションの作成」へ進み、「Pages」のタブで「Gitに接続」
対象のリポジトリを選択して「セットアップの開始」
ビルドの設定にはHugoのプリセットがあるので、選択して「保存してデプロイする」を実行するだけです。
しばらく待つとビルドが完了し、静的ページの公開が完了します。
以降はmainブランチへpushするだけで自動的に再ビルドされ、ブログが更新されます。
あとはMarkdownで記事を作ってゆくだけです。
Discussion