Skip to content

Commit 5b07264

Browse files
committed
POST 3: create blog with obsidian and hugo
1 parent f435804 commit 5b07264

File tree

58 files changed

+5918
-271
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+5918
-271
lines changed

.github/workflows/hugo.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ jobs:
6161
run: |
6262
hugo \
6363
--gc \
64-
--minify \
6564
--baseURL "${{ steps.pages.outputs.base_url }}/"
6665
- name: Upload artifact
6766
uses: actions/upload-pages-artifact@v3

config/_default/params.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ forgejoDefaultServer = "https://v8.next.forgejo.org"
8181
showAuthorsBadges = false
8282
showWordCount = true
8383
sharingLinks = [ "linkedin", "twitter", "bluesky", "mastodon", "reddit", "pinterest", "facebook", "email", "whatsapp", "telegram"]
84-
showZenMode = false
84+
showZenMode = true
8585

8686
[list]
8787
showHero = true
830 KB
Binary file not shown.
45.6 KB
Loading
108 KB
Loading
149 KB
Loading
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
---
2+
title: Obsidian + Hugo + Github pages Blog
3+
published: 2025-02-08T13:52:03
4+
modified: 2025-03-02T15:45:30+01:00
5+
draft: false
6+
description: How to set up blog using obsidian + hugo + github pages.
7+
tags:
8+
- hugo
9+
- obsidian
10+
- bash
11+
- tutorial
12+
- github-pages
13+
- git
14+
---
15+
16+
This is a step-by-step guide on how I created the blog you’re reading right now.
17+
18+
You can find all the code in my repo.
19+
{{< github repo="solumath/blog" >}}
20+
21+
## Why Write a Blog?
22+
23+
Ever wanted to share your experiences or projects but weren’t sure where or how to start? That’s exactly how I’ve felt. I have been working on so many projects lately and I wanted to share a little bit of my experience.
24+
25+
I'm not a professional writer, but a professional "fuck stuff up" guy and believe me that happens more often than it should. Most of the time it pays off and I learn from these mistakes and that's why you are reading this.
26+
27+
If you’re setting up your own blog, don’t be afraid to fuck things up a bit. You’ll learn way more from experimenting than just following a guide on the internet.
28+
29+
## Blog Options
30+
31+
When I was considering writing my own blog my biggest priority was convenience. I wanted something that fit my workflow.
32+
33+
As I recently started using Obsidian I was looking into options how to take advantage of that.
34+
35+
Mostly I didn't want to be tied down by a specific format which would make transition to different format challenging in the future.
36+
37+
### Obsidian Publish
38+
39+
[Obsidian publish](https://obsidian.md/publish) is pretty nice if you want something that works out of the box. Is completely compatible with Obsidian and has some customisation.
40+
41+
Unfortunately it's a paid service of $8/month that is with yearly subscription, $10 if you go monthly. Maximum size of site is 4 GB.
42+
43+
I don't want to be bothered by limited size of my page or other specifications which I would need to tip toe around.
44+
45+
I agree that for most people this solution is okay. But if you want it cheap there's better way.
46+
47+
### Quartz
48+
49+
[Quartz](https://github.com/jackyzha0/quartz) is an open source alternative to Obsidian publish. It fully supports Obsidian and is customizable.
50+
51+
However customisation is harder and there is not that much community driven themes that I would find pleasing. The layout is similar to Obsidian vault which makes it impractical for blog site.
52+
53+
### Hugo
54+
55+
[Hugo](https://github.com/gohugoio/hugo) is an open source framework that generates static sites from markdown files. It is not fully Obsidian compatible but I chose it anyway.
56+
57+
I selected this framework for 4 key reasons:
58+
- Open source -> I can see how the code works
59+
- Generates static files -> can be hosted on GitHub pages
60+
- Fairly popular -> easier to find resolution for problems
61+
- Customisable with community themes
62+
63+
To be honest, setting up Hugo is easy but there are some obstacles and it is not plug and play. However, I was confident that I could make the most of its features and reach the desired result.
64+
65+
## Setting up Obsidian with Hugo
66+
67+
### Workflow
68+
69+
The process of writing blog is simple:
70+
1. Write the post in Obsidian
71+
2. Copy blog post using shell-commands plugin to a git repository
72+
3. Generate content and check the outcome in browser
73+
4. Push to GitHub
74+
5. GitHub workflow will deploy the page automatically on push to main branch
75+
76+
{{< mermaid >}}
77+
%%{
78+
init: {
79+
'theme': 'base',
80+
'themeVariables': {
81+
'primaryColor': '#262626',
82+
'primaryTextColor': '#fff',
83+
'primaryBorderColor': '#69e1ff',
84+
'lineColor': '#fff',
85+
'tertiaryColor': '#fff'
86+
}
87+
}
88+
}%%
89+
graph TD;
90+
A[Obsidian] --> B[Git Repository] --> C[Hugo] --> D[GitHub] --> E[GitHub Pages]
91+
{{< /mermaid >}}
92+
93+
## Tools
94+
95+
- [Obsidian](https://obsidian.md/)
96+
- [Hugo](https://gohugo.io/)
97+
- [Git](https://git-scm.com/)
98+
- [GitHub account](https://github.com/)
99+
100+
## Step by step
101+
102+
### Obsidian
103+
104+
{{< alert icon="lightbulb" >}}
105+
Check [My Obsidian Setup](https://solumath.cz/posts/002-my-obsidian-setup/) before continuing here. I have summed my settings and plugins, which are necessary for the blog.
106+
{{< /alert >}}
107+
108+
Using Hugo with Obsidian brings some limitations. So to have the least amount of work when publishing from Obsidian I follow these rules.
109+
110+
#### 1. Directory Structure
111+
112+
`Choose your blog structure`
113+
114+
Hugo supports 2 styles of directory structure.
115+
1. Directory as a post where you need to supply `index.md`
116+
117+
```txt
118+
├─ blog
119+
├─ posts
120+
├─ 01-post-name
121+
├─ index.md
122+
└─ images
123+
└─ image-name.jpg
124+
```
125+
126+
2. Single markdown files as a post
127+
```txt
128+
├─ blog
129+
├─ posts
130+
├─ 01-post-name.md
131+
└─ 02-post-name.md
132+
```
133+
134+
Here I went with first option because it keeps assets together as I have images or other material for the posts.
135+
136+
Another tip is the numbering in front of post names for two things. First you will know how many posts you have. And second you know the order in which they came out and would have been difficult to filter later.
137+
138+
#### 2. Front Matter Template
139+
140+
`Every post must have a Front matter`
141+
142+
[Front matter](https://gohugo.io/content-management/front-matter/) is part of file which includes metadata used by Hugo to decide what to do with content. You can use [Templater](https://github.com/SilentVoid13/Templater) plugin for more complex templates but the integrated templates were good enough for me.
143+
144+
My blog template looks like this.
145+
```yaml
146+
---
147+
title:
148+
published: {{date}}T{{time}}
149+
modified:
150+
draft: true
151+
summary:
152+
tags:
153+
---
154+
```
155+
156+
For Hugo to parse the `published` metadata correctly you need to follow [dates format](https://gohugo.io/content-management/front-matter/#dates).
157+
158+
Here I encountered the first problem!
159+
160+
When publishing posts they won't appear if their time is in future. So let's say you provided the correct time and the post isn't on the blog. What now?
161+
162+
By default Hugo will make assumption that your time zone is UTC. This might be bothering because sometimes you just create a quick post or want to test something out and you don't see your post on the page.
163+
164+
To fix this you need to use `HH:mm:ssZ` for your time format. This will add your zone shift to the time.
165+
166+
#### 3. Naming Files
167+
168+
`Replace white chars in file names with dashes`
169+
170+
To avoid formatting problem when migrating Obsidian markdown to regular markdown I name my files so that any white chars are replaced with dashes.
171+
That's because Obsidian uses char `%20` for white chars which are incompatible with regular markdown.
172+
173+
Example
174+
175+
From: `001 hello world.md`
176+
177+
To: `001-hello-world.md`
178+
179+
### GitHub Repository
180+
181+
Create repository with name `[your-name].github.io`.
182+
![](images/github-new-repo.png)
183+
184+
And copy your repository.
185+
```bash
186+
git clone [email protected]:[your-name]/[your-name].github.io.git
187+
```
188+
189+
### Hugo
190+
191+
Every Hugo theme has its own options how to install it. I use git modules since it is easy to update and there won't be conflicts with my changes.
192+
193+
For my page I used `Blowfish theme`. Follow their [installation guide](https://blowfish.page/docs/installation/).
194+
195+
After you are done you should have structure similar to this
196+
```txt
197+
.
198+
├── assets
199+
│ └── img
200+
│ └── author.jpg
201+
├── config
202+
│ └── _default
203+
├── content
204+
│ ├── _index.md
205+
│ ├── about.md
206+
│ └── posts
207+
│ └── _index.md
208+
└── themes
209+
└── blowfish
210+
```
211+
212+
Now all that's left is to copy our posts from obsidian to `content/posts`. You can do it with CLI or use the shell-commands plugin.
213+
```bash
214+
# macro for shell-commands
215+
# {{!_blog_path}} is my custom defined variable
216+
cp -a {{!vault_path}}/[your-name].github.io/* {{!_blog_path}}/content/posts
217+
```
218+
219+
Generate the content for Hugo using
220+
```bash
221+
hugo
222+
```
223+
224+
Or if you want to run the server to see the changes
225+
```bash
226+
hugo serve
227+
```
228+
229+
Both of these commands will create static content in public folder which you need to commit too.
230+
231+
Commit your changes after you are done
232+
```bash
233+
git add .
234+
git commit -m "new post"
235+
```
236+
237+
### GitHub Pages
238+
239+
For deploying our blog we will need our domain and server so users can see our website.
240+
241+
Fortunately GitHub has free service called [GitHub Pages](https://pages.github.com/) which offers you subdomain and server. Which is perfect for testing deployment for such project. This however comes with [limits](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#limits-on-use-of-github-pages) as what your page can do:
242+
243+
1. Only static content, no databases or dynamic content. That means you can't have comments on your website if you later wanted to add them.
244+
2. Site can't be larger than 1 GB.
245+
3. Maximum bandwidth of 100 GB per month.
246+
4. and more ...
247+
248+
#### 1. Create GitHub Page
249+
250+
To create GitHub page follow their [documentation](https://docs.github.com/en/pages).
251+
For our use case we will change the workflow how to deploy the page.
252+
253+
When you setup your repository go to settings and change the Build and deployment source to GitHub Actions.
254+
![](images/github-pages-settings.png)
255+
256+
#### 2. Create GitHub Workflow
257+
258+
Follow the [Hugo documentation](https://gohugo.io/hosting-and-deployment/hosting-on-github/).
259+
260+
Here is copy of my workflow that makes sure that anytime I push the changes to `main` branch, the page will be rebuilt and pushed online.
261+
262+
Paste this into `.github/workflows/hugo.yaml`.
263+
264+
{{< codeimporter url="https://raw.githubusercontent.com/solumath/Blog/refs/heads/main/.github/workflows/hugo.yaml" type="yaml" >}}
265+
266+
After you are done with changes you can just push it to GitHub
267+
```bash
268+
git add .
269+
git commit -m "add hugo deployment"
270+
```
271+
272+
### Push
273+
274+
After you committed all your changes and have the workflow setup. You can push your changes to your repository
275+
```bash
276+
git push
277+
```
278+
279+
And after a while you should see your blog at <https://[your-name].github.io>.
280+
281+
# References
282+
283+
- <https://github.com/solumath/Blog>
284+
- <https://obsidian.md/>
285+
- <https://github.com/jackyzha0/quartz>
286+
- <https://git-scm.com/>
287+
- <https://github.com/>
288+
- <https://docs.github.com>
289+
- <https://gohugo.io/>
290+
- <https://github.com/SilentVoid13/Templater>
291+
- <https://blowfish.page/>

public/404.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!DOCTYPE html>
22
<html lang="en" dir="ltr" class="scroll-smooth" data-default-appearance="dark"
3-
data-auto-appearance="true"><head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script>
3+
data-auto-appearance="true"><head>
44
<meta charset="utf-8" />
55

66
<meta http-equiv="content-language" content="en" />
@@ -15,7 +15,7 @@
1515

1616

1717

18-
<link rel="canonical" href="http://localhost:1313/404.html" />
18+
<link rel="canonical" href="https://solumath.cz/404.html" />
1919

2020

2121

@@ -46,8 +46,8 @@
4646

4747

4848

49-
<script defer type="text/javascript" id="script-bundle" src="/js/main.bundle.min.a2d78d78672e549fbfc972ece871725b5478ba0b65708dda20cb97ab80a865eae6d247e1b05a4aec6ebbf78647ec3233bad8b2609ed98eee53cd58aa17128bc7.js"
50-
integrity="sha512-oteNeGcuVJ&#43;/yXLs6HFyW1R4ugtlcI3aIMuXq4CoZerm0kfhsFpK7G6794ZH7DIzutiyYJ7Zju5TzViqFxKLxw==" data-copy="" data-copied=""></script>
49+
<script defer type="text/javascript" id="script-bundle" src="/js/main.bundle.min.65b5de43825ad54a420102c9ddccece1f1015665fe76e5b399ba259e1de29f6c83ac1b3cf77beed3d29e26604dfebf561a8e1db523cb6add0d6acccc9e8f1307.js"
50+
integrity="sha512-ZbXeQ4Ja1UpCAQLJ3czs4fEBVmX&#43;duWzmbolnh3in2yDrBs893vu09KeJmBN/r9WGo4dtSPLat0NaszMno8TBw==" data-copy="" data-copied=""></script>
5151

5252

5353

@@ -67,7 +67,7 @@
6767

6868

6969

70-
<meta property="og:url" content="http://localhost:1313/404.html">
70+
<meta property="og:url" content="https://solumath.cz/404.html">
7171
<meta property="og:site_name" content="Solumath">
7272
<meta property="og:title" content="404 Page not found">
7373
<meta property="og:locale" content="en">
@@ -482,7 +482,7 @@ <h1 class="mb-3 text-4xl font-extrabold">Page Not Found 😕</h1>
482482
<div
483483
id="search-wrapper"
484484
class="invisible fixed inset-0 flex h-screen w-screen cursor-default flex-col bg-neutral-500/50 p-4 backdrop-blur-sm dark:bg-neutral-900/50 sm:p-6 md:p-[10vh] lg:p-[12vh]"
485-
data-url="http://localhost:1313/"
485+
data-url="https://solumath.cz/"
486486
style="z-index:500"
487487
>
488488
<div

0 commit comments

Comments
 (0)