<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Static-Site on Canh Dinh</title><link>https://blog.canhdinh.com/tags/static-site/</link><description>Recent content in Static-Site on Canh Dinh</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 21 Jun 2026 18:47:39 +0700</lastBuildDate><atom:link href="https://blog.canhdinh.com/tags/static-site/index.xml" rel="self" type="application/rss+xml"/><item><title>Deploy Static Site With Hugo and Cloudflare Workers</title><link>https://blog.canhdinh.com/posts/deploy-static-site-with-hugo-cloudflare/</link><pubDate>Sun, 21 Jun 2026 18:47:39 +0700</pubDate><guid>https://blog.canhdinh.com/posts/deploy-static-site-with-hugo-cloudflare/</guid><description>&lt;p&gt;In this post, I’ll walk through how I deployed my personal static blog using &lt;a href="https://gohugo.io/"&gt;Hugo&lt;/a&gt;, the &lt;a href="https://github.com/adityatelange/hugo-PaperMod"&gt;PaperMod&lt;/a&gt; theme, &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt;, and &lt;a href="https://developers.cloudflare.com/workers/"&gt;Cloudflare Workers&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A note on Workers vs. Pages:&lt;/strong&gt; Cloudflare is consolidating static site hosting from Cloudflare Pages into Cloudflare Workers. As of 2025, &lt;a href="https://developers.cloudflare.com/workers/static-assets/"&gt;Workers Static Assets&lt;/a&gt; is the recommended way to host new static sites, and Pages is in maintenance mode. In the dashboard both still live under the unified &lt;strong&gt;Workers &amp;amp; Pages&lt;/strong&gt; section, which is why the deploy commands below use &lt;code&gt;wrangler deploy&lt;/code&gt; (a Workers command) rather than the older Pages workflow.&lt;/p&gt;</description><content:encoded><![CDATA[<p>In this post, I’ll walk through how I deployed my personal static blog using <a href="https://gohugo.io/">Hugo</a>, the <a href="https://github.com/adityatelange/hugo-PaperMod">PaperMod</a> theme, <a href="https://github.com/">GitHub</a>, and <a href="https://developers.cloudflare.com/workers/">Cloudflare Workers</a>.</p>
<blockquote>
<p><strong>A note on Workers vs. Pages:</strong> Cloudflare is consolidating static site hosting from Cloudflare Pages into Cloudflare Workers. As of 2025, <a href="https://developers.cloudflare.com/workers/static-assets/">Workers Static Assets</a> is the recommended way to host new static sites, and Pages is in maintenance mode. In the dashboard both still live under the unified <strong>Workers &amp; Pages</strong> section, which is why the deploy commands below use <code>wrangler deploy</code> (a Workers command) rather than the older Pages workflow.</p>
</blockquote>
<p>This is the setup I use for my own blog:</p>
<ul>
<li>GitHub repository: <a href="https://github.com/vancanhuit/personal-blog">vancanhuit/personal-blog</a></li>
<li>Live site: <a href="https://blog.canhdinh.com/">blog.canhdinh.com</a></li>
<li>Static site generator: <a href="https://gohugo.io/">Hugo</a></li>
<li>Theme: <a href="https://github.com/adityatelange/hugo-PaperMod">PaperMod</a></li>
<li>Hosting/deployment: <a href="https://developers.cloudflare.com/workers/static-assets/">Cloudflare Workers (Static Assets)</a></li>
</ul>
<p>The final Cloudflare build and deploy commands are:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git submodule update --init --recursive <span class="o">&amp;&amp;</span> hugo --gc --minify
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npx wrangler deploy --assets<span class="o">=</span>public --name personal-blog --compatibility-date 2026-06-21
</span></span></code></pre></td></tr></table>
</div>
</div><p>No <code>wrangler.jsonc</code> file is required in the repository for this setup.</p>
<h2 id="why-hugo">Why Hugo?</h2>
<p><a href="https://gohugo.io/">Hugo</a> is a static site generator written in Go. It is fast, simple, and works very well for technical blogs.</p>
<p>A static blog is a good fit for my use case because I mostly write posts that contain:</p>
<ul>
<li>Markdown content</li>
<li>Source code examples</li>
<li>DevOps notes</li>
<li>Infrastructure experiments</li>
</ul>
<p>Since Hugo generates plain HTML, CSS, JavaScript, images, and fonts, the final site is easy to host on Cloudflare.</p>
<h2 id="why-papermod">Why PaperMod?</h2>
<p>I chose <a href="https://github.com/adityatelange/hugo-PaperMod">PaperMod</a> because it is clean, fast, and works well for technical writing.</p>
<p>Some features I wanted:</p>
<ul>
<li>Clean blog layout</li>
<li>Dark/light mode</li>
<li>Table of contents</li>
<li>Reading time</li>
<li>Tags and categories</li>
<li>Good source code block rendering</li>
<li>Code copy button</li>
<li>Minimal maintenance</li>
</ul>
<p>For a technical blog, PaperMod is a practical choice because it stays out of the way and lets the content stand out.</p>
<h2 id="create-the-hugo-site">Create the Hugo site</h2>
<p>Create a new Hugo project. By default Hugo generates a TOML config file, so pass <code>--format yaml</code> to get <code>hugo.yaml</code> instead:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo new site personal-blog --format yaml
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> personal-blog
</span></span><span class="line"><span class="cl">git init
</span></span></code></pre></td></tr></table>
</div>
</div><p>Then add PaperMod as a Git submodule:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git submodule add https://github.com/adityatelange/hugo-PaperMod themes/PaperMod
</span></span></code></pre></td></tr></table>
</div>
</div><p>Because PaperMod is added as a submodule, the repository will include a <code>.gitmodules</code> file.</p>
<p>You can check it with:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cat .gitmodules
</span></span></code></pre></td></tr></table>
</div>
</div><p>Example:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[submodule &#34;themes/PaperMod&#34;]</span>
</span></span><span class="line"><span class="cl">  <span class="na">path</span> <span class="o">=</span> <span class="s">themes/PaperMod
</span></span></span><span class="line"><span class="cl"><span class="s">  url = https://github.com/adityatelange/hugo-PaperMod</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="configure-hugo">Configure Hugo</h2>
<p>Here is a simplified <code>hugo.yaml</code> configuration:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">baseURL</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://blog.canhdinh.com/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">locale</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;en-us&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Canh Dinh&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">theme</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;PaperMod&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">pagination</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">pagerSize</span><span class="p">:</span><span class="w"> </span><span class="m">10</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">outputs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">home</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">HTML</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">RSS</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">JSON</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">env</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;production&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Notes on DevOps practices, self-hosting and software delivery.&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">author</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Canh Dinh&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">mainSections</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">posts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">homeInfoParams</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">Title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Hi there 👋&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">Content</span><span class="p">:</span><span class="w"> </span><span class="p">&gt;</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">      Welcome to my blog.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">defaultTheme</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;auto&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">disableThemeToggle</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowReadingTime</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowShareButtons</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowPostNavLinks</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowBreadCrumbs</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowCodeCopyButtons</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowWordCount</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowRssButtonInSectionTermList</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ShowToc</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">TocOpen</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">UseHugoToc</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">socialIcons</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;github&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://github.com/vancanhuit&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">menu</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">main</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;tags&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Tags&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/tags/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">20</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;archives&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Archives&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/archives/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">30</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;search&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Search&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/search/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">40</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">markup</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">highlight</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">codeFences</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">guessSyntax</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">lineNos</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">lineNumbersInTable</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">noClasses</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>The most important values are:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">baseURL</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://blog.canhdinh.com/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">theme</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;PaperMod&#34;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>The <code>baseURL</code> should match the production domain.</p>
<p>A few PaperMod-specific options are worth highlighting:</p>
<ul>
<li><code>mainSections: [posts]</code> makes the home page (<code>/</code>) list posts from <code>content/posts/</code>, so the landing page acts as the posts archive.</li>
<li><code>homeInfoParams</code> renders an intro block (title plus content) at the top of the home page, followed by the post list.</li>
<li><code>outputs.home</code> adds a <code>JSON</code> output, which generates the search index used by the search page.</li>
</ul>
<h2 id="home-archives-and-search-pages">Home, archives, and search pages</h2>
<p>PaperMod renders the post list on the home page automatically, but the <strong>Archives</strong> and <strong>Search</strong> pages each need a content file that selects the right layout. Without them, the menu links return <code>404</code>.</p>
<p>Create the archives page:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo new content archives.md
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: &#34;Archives&#34;
</span></span><span class="line"><span class="cl">layout: &#34;archives&#34;
</span></span><span class="line"><span class="cl">url: &#34;/archives/&#34;
</span></span><span class="line"><span class="cl">summary: &#34;archives&#34;
</span></span><span class="line"><span class="cl">---
</span></span></code></pre></td></tr></table>
</div>
</div><p>Create the search page:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo new content search.md
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: &#34;Search&#34;
</span></span><span class="line"><span class="cl">layout: &#34;search&#34;
</span></span><span class="line"><span class="cl">url: &#34;/search/&#34;
</span></span><span class="line"><span class="cl">summary: &#34;search&#34;
</span></span><span class="line"><span class="cl">placeholder: &#34;Search posts...&#34;
</span></span><span class="line"><span class="cl">---
</span></span></code></pre></td></tr></table>
</div>
</div><p>The search page relies on the <code>JSON</code> home output configured above. PaperMod ships with <a href="https://www.fusejs.io/">Fuse.js</a> and performs fuzzy, client-side search over that index, so no server-side component is required.</p>
<h2 id="add-a-blog-post">Add a blog post</h2>
<p>Create a new post:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo new content posts/hello-world.md
</span></span></code></pre></td></tr></table>
</div>
</div><p>Example post:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: &#34;Hello World&#34;
</span></span><span class="line"><span class="cl">date: 2026-06-21T10:00:00+07:00
</span></span><span class="line"><span class="cl">draft: false
</span></span><span class="line"><span class="cl">tags: [&#34;hugo&#34;, &#34;cloudflare&#34;, &#34;devops&#34;]
</span></span><span class="line"><span class="cl">categories: [&#34;devops&#34;]
</span></span><span class="line"><span class="cl">showToc: true
</span></span><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">This is my first post using Hugo, PaperMod, GitHub, and Cloudflare.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="s">```go
</span></span></span><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;fmt&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Hello from my blog&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="s">```</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Make sure the post has:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">draft</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>If <code>draft</code> is set to <code>true</code>, Hugo will not publish it in production builds.</p>
<h2 id="run-locally">Run locally</h2>
<p>For local development, run:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo server -D --disableFastRender
</span></span></code></pre></td></tr></table>
</div>
</div><p>Then open:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">http://localhost:1313
</span></span></code></pre></td></tr></table>
</div>
</div><p>The <code>-D</code> flag includes draft posts.</p>
<p>If the site looks stale after changing CSS, fonts, or theme files, clean the generated output:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">rm -rf public resources/_gen
</span></span><span class="line"><span class="cl">hugo --gc --minify
</span></span><span class="line"><span class="cl">hugo server -D --disableFastRender
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="self-host-fonts">Self-host fonts</h2>
<p>I self-host two fonts so the site does not depend on a third-party font CDN:</p>
<ul>
<li><a href="https://github.com/rsms/inter">Inter</a> for body and UI text.</li>
<li><a href="https://github.com/subframe7536/maple-font">Maple Mono NL</a> for code blocks.</li>
</ul>
<p>Font files are stored under:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">static/fonts/inter/
</span></span><span class="line"><span class="cl">static/fonts/maple-mono/
</span></span></code></pre></td></tr></table>
</div>
</div><p>For example:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">static/fonts/maple-mono/MapleMonoNL-Regular.ttf.woff2
</span></span><span class="line"><span class="cl">static/fonts/maple-mono/MapleMonoNL-Bold.ttf.woff2
</span></span><span class="line"><span class="cl">static/fonts/maple-mono/MapleMonoNL-Italic.ttf.woff2
</span></span></code></pre></td></tr></table>
</div>
</div><p>Then I define the font in:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">assets/css/extended/custom-fonts.css
</span></span></code></pre></td></tr></table>
</div>
</div><p>Example:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">@</span><span class="k">font-face</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-family</span><span class="o">:</span> <span class="s2">&#34;Maple Mono NL&#34;</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">src</span><span class="o">:</span> <span class="nt">url</span><span class="o">(</span><span class="s2">&#34;/fonts/maple-mono/MapleMonoNL-Regular.ttf.woff2&#34;</span><span class="o">)</span> <span class="nt">format</span><span class="o">(</span><span class="s2">&#34;woff2&#34;</span><span class="o">);</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-weight</span><span class="o">:</span> <span class="nt">400</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-style</span><span class="o">:</span> <span class="nt">normal</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-display</span><span class="o">:</span> <span class="nt">swap</span><span class="o">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">@</span><span class="k">font-face</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-family</span><span class="o">:</span> <span class="s2">&#34;Maple Mono NL&#34;</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">src</span><span class="o">:</span> <span class="nt">url</span><span class="o">(</span><span class="s2">&#34;/fonts/maple-mono/MapleMonoNL-Bold.ttf.woff2&#34;</span><span class="o">)</span> <span class="nt">format</span><span class="o">(</span><span class="s2">&#34;woff2&#34;</span><span class="o">);</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-weight</span><span class="o">:</span> <span class="nt">700</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-style</span><span class="o">:</span> <span class="nt">normal</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-display</span><span class="o">:</span> <span class="nt">swap</span><span class="o">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nt">code</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="nt">pre</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="nt">kbd</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="nt">samp</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">highlight</span> <span class="nt">pre</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">highlight</span> <span class="nt">code</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">chroma</span><span class="o">,</span>
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">chroma</span> <span class="nt">code</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">font-family</span><span class="p">:</span> <span class="s2">&#34;Maple Mono NL&#34;</span><span class="p">,</span> <span class="n">ui-monospace</span><span class="p">,</span> <span class="n">SFMono-Regular</span><span class="p">,</span> <span class="n">Menlo</span><span class="p">,</span> <span class="n">Monaco</span><span class="p">,</span> <span class="n">Consolas</span><span class="p">,</span> <span class="s2">&#34;Liberation Mono&#34;</span><span class="p">,</span> <span class="kc">monospace</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">font-feature-settings</span><span class="p">:</span> <span class="s2">&#34;liga&#34;</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&#34;calt&#34;</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">font-variant-ligatures</span><span class="p">:</span> <span class="kc">none</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>I disable ligatures because I prefer code to display exactly as typed.</p>
<p>For body text, I load Inter as a variable font (two <code>woff2</code> files cover every weight) and set it as the base font:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">@</span><span class="k">font-face</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-family</span><span class="o">:</span> <span class="s2">&#34;Inter&#34;</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">src</span><span class="o">:</span> <span class="nt">url</span><span class="o">(</span><span class="s2">&#34;/fonts/inter/inter-latin-wght-normal.woff2&#34;</span><span class="o">)</span> <span class="nt">format</span><span class="o">(</span><span class="s2">&#34;woff2-variations&#34;</span><span class="o">);</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-weight</span><span class="o">:</span> <span class="nt">100</span> <span class="nt">900</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-style</span><span class="o">:</span> <span class="nt">normal</span><span class="o">;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">font-display</span><span class="o">:</span> <span class="nt">swap</span><span class="o">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nt">body</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">font-family</span><span class="p">:</span> <span class="s2">&#34;Inter&#34;</span><span class="p">,</span> <span class="o">-</span><span class="n">apple-system</span><span class="p">,</span> <span class="n">BlinkMacSystemFont</span><span class="p">,</span> <span class="s2">&#34;Segoe UI&#34;</span><span class="p">,</span> <span class="n">Roboto</span><span class="p">,</span> <span class="n">Helvetica</span><span class="p">,</span> <span class="n">Arial</span><span class="p">,</span> <span class="kc">sans-serif</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Because the extended stylesheet loads after the theme&rsquo;s CSS, this <code>body</code> rule overrides PaperMod&rsquo;s default font stack.</p>
<h2 id="custom-styling">Custom styling</h2>
<p>PaperMod automatically bundles any CSS placed in <code>assets/css/extended/</code>, loaded after the theme styles. I use a <code>custom.css</code> file there to make the content stand out and improve reading comfort:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">assets/css/extended/custom.css
</span></span></code></pre></td></tr></table>
</div>
</div><p>The main tweaks are:</p>
<ul>
<li>An accent color for in-content links, with the default underline removed and an underline that animates in on hover.</li>
<li>Styled blockquotes with an accent border, a tinted background, and a decorative quote mark.</li>
<li>Subtle borders on inline code, rounded tables with a shaded header row, and a slim centered horizontal rule.</li>
<li>A softer light palette and brighter dark-mode text, plus a larger line height for more comfortable reading.</li>
</ul>
<p>All colors are driven by CSS variables (including PaperMod&rsquo;s own <code>--theme</code>, <code>--content</code>, and <code>--border</code>) and an <code>--accent</code> variable defined separately for light and <code>.dark</code> modes, so the styling adapts to both themes:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-css" data-lang="css"><span class="line"><span class="cl"><span class="p">:</span><span class="nd">root</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nv">--accent</span><span class="p">:</span> <span class="mh">#2563eb</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">dark</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nv">--accent</span><span class="p">:</span> <span class="mh">#6ea8fe</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">post-content</span> <span class="nt">a</span><span class="p">:</span><span class="nd">not</span><span class="o">(</span><span class="p">.</span><span class="nc">anchor</span><span class="o">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">color</span><span class="p">:</span> <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="n">accent</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">text-decoration</span><span class="p">:</span> <span class="kc">none</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">.</span><span class="nc">post-content</span> <span class="nt">blockquote</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">border-inline-start</span><span class="p">:</span> <span class="mf">0.25</span><span class="kt">rem</span> <span class="kc">solid</span> <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="n">accent</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">background</span><span class="p">:</span> <span class="nf">var</span><span class="p">(</span><span class="o">--</span><span class="n">quote</span><span class="o">-</span><span class="n">bg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>PaperMod underlines content links through <code>.md-content a:not(.anchor)</code>. Because that selector has a higher specificity than a plain <code>.post-content a</code>, the override matches it with <code>.post-content a:not(.anchor)</code> so the default underline is actually removed.</p>
<h2 id="push-to-github">Push to GitHub</h2>
<p>Commit and push the project:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git add .
</span></span><span class="line"><span class="cl">git commit -m <span class="s2">&#34;Initial Hugo blog with PaperMod&#34;</span>
</span></span><span class="line"><span class="cl">git branch -M main
</span></span><span class="line"><span class="cl">git remote add origin https://github.com/vancanhuit/personal-blog.git
</span></span><span class="line"><span class="cl">git push -u origin main
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="configure-cloudflare-deployment">Configure Cloudflare deployment</h2>
<p>In the Cloudflare dashboard, go to <strong>Workers &amp; Pages</strong>, create a new Worker, connect the GitHub repository, and configure the project with these commands.</p>
<h3 id="build-command">Build command</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git submodule update --init --recursive <span class="o">&amp;&amp;</span> hugo --gc --minify
</span></span></code></pre></td></tr></table>
</div>
</div><p>This does two things:</p>
<ol>
<li>Fetches the PaperMod theme submodule.</li>
<li>Builds and minifies the Hugo site into the <code>public/</code> directory.</li>
</ol>
<p>The <code>git submodule update --init --recursive</code> part is important because PaperMod is stored as a Git submodule.</p>
<h3 id="deploy-command">Deploy command</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npx wrangler deploy --assets<span class="o">=</span>public --name personal-blog --compatibility-date 2026-06-21
</span></span></code></pre></td></tr></table>
</div>
</div><p>This deploys the generated <code>public/</code> directory as static assets.</p>
<p>In this setup, I do not need a <code>wrangler.jsonc</code> file in the repository because the deploy command provides the required Workers deployment options directly:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">--assets<span class="o">=</span>public
</span></span><span class="line"><span class="cl">--name personal-blog
</span></span><span class="line"><span class="cl">--compatibility-date 2026-06-21
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="environment-variables">Environment variables</h2>
<p>I also recommend setting <code>HUGO_VERSION</code> in Cloudflare:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">HUGO_VERSION = 0.163.3
</span></span></code></pre></td></tr></table>
</div>
</div><p>Using a fixed Hugo version helps avoid unexpected build differences between local and Cloudflare environments.</p>
<h2 id="normal-publishing-workflow">Normal publishing workflow</h2>
<p>After the initial setup, publishing a new post is simple.</p>
<p>Create a post:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo new content posts/my-new-post.md
</span></span></code></pre></td></tr></table>
</div>
</div><p>Preview locally:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">hugo server -D --disableFastRender
</span></span></code></pre></td></tr></table>
</div>
</div><p>When ready, commit and push:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git add .
</span></span><span class="line"><span class="cl">git commit -m <span class="s2">&#34;Add new blog post&#34;</span>
</span></span><span class="line"><span class="cl">git push
</span></span></code></pre></td></tr></table>
</div>
</div><p>Cloudflare will automatically rebuild and redeploy the site.</p>
<h2 id="troubleshooting">Troubleshooting</h2>
<h3 id="theme-is-missing">Theme is missing</h3>
<p>If Cloudflare cannot find PaperMod, make sure the theme submodule is committed:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git submodule status
</span></span><span class="line"><span class="cl">cat .gitmodules
</span></span></code></pre></td></tr></table>
</div>
</div><p>Also make sure the build command includes:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git submodule update --init --recursive
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="code-blocks-look-broken">Code blocks look broken</h3>
<p>Clean Hugo’s generated files locally:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">rm -rf public resources/_gen
</span></span><span class="line"><span class="cl">hugo --gc --minify
</span></span><span class="line"><span class="cl">hugo server -D --disableFastRender
</span></span></code></pre></td></tr></table>
</div>
</div><p>Also check the Markdown code fence format:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="s">```go
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;hello&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="s">```</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="new-font-does-not-appear">New font does not appear</h3>
<p>Hard refresh the browser:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Ctrl + Shift + R
</span></span></code></pre></td></tr></table>
</div>
</div><p>On macOS:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Cmd + Shift + R
</span></span></code></pre></td></tr></table>
</div>
</div><p>If fonts are cached aggressively, rename the font folder or font files and update the CSS paths.</p>
<h3 id="deployment-fails-after-successful-build">Deployment fails after successful build</h3>
<p>If the log shows that Hugo built successfully but deployment failed, check the deploy command.</p>
<p>For this setup, use:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npx wrangler deploy --assets<span class="o">=</span>public --name personal-blog --compatibility-date 2026-06-21
</span></span></code></pre></td></tr></table>
</div>
</div><p>not just:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">npx wrangler deploy
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="useful-links">Useful links</h2>
<ul>
<li><a href="https://gohugo.io/">Hugo official website</a></li>
<li><a href="https://gohugo.io/documentation/">Hugo documentation</a></li>
<li><a href="https://github.com/adityatelange/hugo-PaperMod">PaperMod GitHub repository</a></li>
<li><a href="https://github.com/adityatelange/hugo-PaperMod/wiki/Installation">PaperMod installation guide</a></li>
<li><a href="https://developers.cloudflare.com/workers/">Cloudflare Workers</a></li>
<li><a href="https://developers.cloudflare.com/workers/static-assets/">Cloudflare Workers static assets</a></li>
<li><a href="https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/">Migrate from Pages to Workers</a></li>
<li><a href="https://developers.cloudflare.com/workers/wrangler/commands/#deploy">Wrangler deploy command</a></li>
</ul>
<h2 id="final-setup">Final setup</h2>
<p>The final setup is:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Hugo static site
</span></span><span class="line"><span class="cl">PaperMod theme
</span></span><span class="line"><span class="cl">GitHub repository
</span></span><span class="line"><span class="cl">Cloudflare build command:
</span></span><span class="line"><span class="cl">  git submodule update --init --recursive &amp;&amp; hugo --gc --minify
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Cloudflare deploy command:
</span></span><span class="line"><span class="cl">  npx wrangler deploy --assets=public --name personal-blog --compatibility-date 2026-06-21
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">No wrangler.jsonc required
</span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded></item></channel></rss>