<?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>Search on Janusworx</title>
    <link>https://janusworx.com/tags/search/</link>
    <description>Recent content in Search on Janusworx</description>
    <image>
      <title>Janusworx</title>
      <url>https://janusworx.com/images/jw-logo.png</url>
      <link>https://janusworx.com/images/jw-logo.png</link>
    </image>
    <generator>Hugo -- 0.163.2</generator>
    <language>en</language>
    <lastBuildDate>Tue, 23 Jun 2026 14:24:24 +0530</lastBuildDate>
    <atom:link href="https://janusworx.com/tags/search/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>You Can Now Search this Blog</title>
      <link>https://janusworx.com/work/you-can-now-search-this-blog/</link>
      <pubDate>Tue, 23 Jun 2026 14:24:24 +0530</pubDate>
      <guid>https://janusworx.com/work/you-can-now-search-this-blog/</guid>
      <description>&lt;br&gt;


            &lt;link rel=&#34;stylesheet&#34; href=&#34;https://janusworx.com/css/vendors/admonitions.53cd9f8afa9d9a8ac09093f668df057bc6d0f4bbd0886f39991a7b99934a7432.css&#34; integrity=&#34;sha256-U82fivqdmorAkJP2aN8Fe8bQ9LvQiG85mRp7mZNKdDI=&#34; crossorigin=&#34;anonymous&#34;&gt;
    &lt;div class=&#34;admonition info&#34;&gt;
      &lt;div class=&#34;admonition-header&#34;&gt;&lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; viewBox=&#34;0 0 512 512&#34;&gt;&lt;path d=&#34;M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336l24 0 0-64-24 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l48 0c13.3 0 24 10.7 24 24l0 88 8 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-80 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-208a32 32 0 1 1 0 64 32 32 0 1 1 0-64z&#34;/&gt;&lt;/svg&gt;
        &lt;span&gt;Intended Audience&lt;/span&gt;
      &lt;/div&gt;
      &lt;div class=&#34;admonition-content&#34;&gt;
        &lt;p&gt;Me. In case I want to retrace the big idea tomorrow&lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;&lt;br&gt;

&lt;figure class=&#34;align-center &#34;&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;https://janusworx.com/images/2026/you-can-now-search-this-blog-pagefind.png#center&#34;
         alt=&#34;Pagefind PNG logo&#34;/&gt; 
&lt;/figure&gt;

&lt;hr style=&#39;margin-left: auto; margin-right: auto; margin-bottom: 40px; margin-top: 50px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238);  height: 1px;&#39;/&gt;

&lt;h3 id=&#34;tldr&#34;&gt;tldr: &lt;a href=&#34;https://janusworx.com/search&#34;&gt;https://janusworx.com/search&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Being the lazyass that I am, I used to depend on search engine indexes to find something on my own blog. (First google, then DuckDuckGo.)&lt;br&gt;
Kushal, having &lt;a href=&#34;https://search.kushaldas.in/&#34;&gt;https://search.kushaldas.in/&lt;/a&gt; has always made me jealous though.&lt;br&gt;
And now, the days of finding something relevant on my blog, on the first search are long gone. Search engines today are a pale shadow of what they used to be. The current load of crap actually makes me long for the days of &lt;a href=&#34;https://en.wikipedia.org/wiki/AltaVista&#34;&gt;Altavista&lt;/a&gt;!&lt;/p&gt;</description>
      <content:encoded><![CDATA[<br>


            <link rel="stylesheet" href="/css/vendors/admonitions.53cd9f8afa9d9a8ac09093f668df057bc6d0f4bbd0886f39991a7b99934a7432.css" integrity="sha256-U82fivqdmorAkJP2aN8Fe8bQ9LvQiG85mRp7mZNKdDI=" crossorigin="anonymous">
    <div class="admonition info">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336l24 0 0-64-24 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l48 0c13.3 0 24 10.7 24 24l0 88 8 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-80 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-208a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>
        <span>Intended Audience</span>
      </div>
      <div class="admonition-content">
        <p>Me. In case I want to retrace the big idea tomorrow</p>
      </div>
    </div><br>

<figure class="align-center ">
    <img loading="lazy" src="/images/2026/you-can-now-search-this-blog-pagefind.png#center"
         alt="Pagefind PNG logo"/> 
</figure>

<hr style='margin-left: auto; margin-right: auto; margin-bottom: 40px; margin-top: 50px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238);  height: 1px;'/>

<h3 id="tldr">tldr: <a href="https://janusworx.com/search">https://janusworx.com/search</a></h3>
<p>Being the lazyass that I am, I used to depend on search engine indexes to find something on my own blog. (First google, then DuckDuckGo.)<br>
Kushal, having <a href="https://search.kushaldas.in/">https://search.kushaldas.in/</a> has always made me jealous though.<br>
And now, the days of finding something relevant on my blog, on the first search are long gone. Search engines today are a pale shadow of what they used to be. The current load of crap actually makes me long for the days of <a href="https://en.wikipedia.org/wiki/AltaVista">Altavista</a>!</p>
<p>So, I decided to get off my butt, and go do something about it, because everytime I want something, my blog is one of the first places I search.<br>
For e.g. when writing this post, I needed to look up how to add line numbers to my code blocks. <a href="/work/line-numbers-in-hugo-codeblocks/">Search helped me find it</a> :)</p>
<p>I went to the <a href="https://gohugo.io/tools/search/">Hugo website</a> and decided to implement the first search tool<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> they suggested: <em><strong><a href="https://pagefind.app">Pagefind</a></strong></em>.<br>
Well, I did that, since it took care of the only thing I’m anal about.<br>
Everything is local and under my control. If not I’d have kept looking for something else.<br>
What it does, is parses the site, Hugo builds for me, and creates a search index along with some more goodies (an api for search as well as UI components) in a bundle. The rendered html and the bundle together are now the artifact that my site is made up of.</p>
<h2 id="the-plan">The Plan</h2>
<ol>
<li>Get Pagefind and install it into a tools subdirectory in my blog’s directory, so I always have it handy (and the Forgejo action can get its grubby paws on it when it wants to run the publishing workflow)</li>
<li>Create an entry in my menu, so I can go clicky to a search page.</li>
<li>Create said search page.</li>
<li>Make search work.</li>
<li>Make the page resemble the rest of the blog as much as possible.</li>
</ol>
<h2 id="installing-it-and-wiring-it-all-up">Installing it and wiring it all up</h2>
<h3 id="1-installation">1. Installation</h3>
<p>This is the easy part. Pagefind is a single binary, which I shoved into the <code>tools</code> subdirectory.</p>
<h3 id="2-creating-an-entry-for-search-in-the-navigation-menu">2. Creating an entry for search in the navigation menu</h3>
<p>I edited my Hugo config (mine is called <code>hugo.yaml</code>), and added <code>search</code> as a menu item.<br>
More shifted downwards, as did its weight.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">menus</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">main</span>: <span style="color:#75715e"># elided config</span>
</span></span><span style="display:flex;"><span>    - <span style="color:#f92672">identifier</span>: <span style="color:#ae81ff">search</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">name</span>: <span style="color:#ae81ff">search</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">url</span>: <span style="color:#ae81ff">/search</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">weight</span>: <span style="color:#ae81ff">60</span>
</span></span><span style="display:flex;"><span>    - <span style="color:#f92672">identifier</span>: <span style="color:#ae81ff">more</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">name</span>: <span style="color:#ae81ff">more …</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">url</span>: <span style="color:#ae81ff">/more/</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">weight</span>: <span style="color:#ae81ff">70</span>
</span></span></code></pre></div><h3 id="3-creating-the-search-page">3. Creating the search page.</h3>
<p>This was a two step process.</p>
<h4 id="a-i-needed-a-placeholder-page-that-i-could-render-some-layout-a-template-into">a. I needed a placeholder page that I could render some layout (a template) into.</h4>
<p>This was <code>search.md</code> which lives in my <code>content</code> directory.
This is all it contains …</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">5
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span><span style="color:#f92672">title</span>: <span style="color:#ae81ff">Search</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">layout</span>: <span style="color:#ae81ff">search</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">url</span>: <span style="color:#ae81ff">/search/</span>
</span></span><span style="display:flex;"><span>---
</span></span></code></pre></td></tr></table>
</div>
</div><p>See the key that says <code>layout</code> on line 3? This is looking for a layout called <code>search</code> which is what we now create …</p>
<h4 id="b-creating-the-search-layout">b. Creating the search layout.</h4>
<p>Papermod already ships with a layout called <code>search</code>. Which I did not want to use because it is meant for use with another local search engine called <a href="https://lunrjs.com/">lunr.js</a>.<br>
Hugo lets you override whatever your theme provides, by letting you create your own versions of said file in the <code>layouts</code> directory. Hugo will then look at <em>that</em> instead of the theme’s file.<br>
Over the years I’ve gotten dangerous enough by using <a href="https://discourse.gohugo.io/t/how-to-override-a-themes-partials/47227">Hugo’s lovely channel for discourse</a>. Between that, and <a href="https://gohugo.io/documentation/">Hugo’s documentation</a> as well as <a href="https://pagefind.app/">Pagefind’s own help page</a>, I rustled up a layout file called <code>search.html</code> which lives in my <code>layouts/_default</code> directory. This is what it contains …</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go-html-template" data-lang="go-html-template"><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#66d9ef">define</span> <span style="color:#e6db74">&#34;main&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">link</span> <span style="color:#a6e22e">rel</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;stylesheet&#34;</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/pagefind/pagefind-component-ui.css&#34;</span>&gt;
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">script</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;module&#34;</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/pagefind/pagefind-component-ui.js&#34;</span>&gt;&lt;/<span style="color:#f92672">script</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;main&#34;</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">article</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;post-single&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">header</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;post-header&#34;</span>&gt;
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">h1</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;post-title&#34;</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">.Title</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">h1</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;/<span style="color:#f92672">header</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;post-content search-content&#34;</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">pagefind-config</span>&gt;&lt;/<span style="color:#f92672">pagefind-config</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">pagefind-input</span> <span style="color:#a6e22e">placeholder</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Search for something …&#34;</span>&gt;&lt;/<span style="color:#f92672">pagefind-input</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">pagefind-summary</span>&gt;&lt;/<span style="color:#f92672">pagefind-summary</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">pagefind-results</span>&gt;&lt;/<span style="color:#f92672">pagefind-results</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    &lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;/<span style="color:#f92672">article</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span></code></pre></div><p>This creates the box on the search page, ready to take input and show results.</p>
<h3 id="4-make-the-page-resemble-the-rest-of-the-blog-as-much-as-possible">4. Make the page resemble the rest of the blog as much as possible.</h3>
<p>Doing things a bit out of order and finishing up with the page first.<br>
Leaned on Pagefind’s docs as well as Chatgpt, Claude and Gemini for this part to create a CSS file, that looks pretty native to my blog. I’ve called it <code>include-pagefind.css</code> and it lives in the <code>assets/css/extended</code> subdirectory.</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 1
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 2
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 3
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 4
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 5
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 6
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 7
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 8
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"> 9
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">10
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">11
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">12
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">13
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">14
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">15
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">16
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">17
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">18
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">19
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">20
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">21
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">22
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">23
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">24
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">25
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">26
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">27
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">28
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">29
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">30
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">31
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">32
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">33
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">34
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">35
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">36
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">37
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">38
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">39
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">40
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">41
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">42
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">43
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">44
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">45
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">46
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">47
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">48
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">49
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">50
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">51
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">52
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">53
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">54
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">55
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">56
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">57
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">58
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">59
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">60
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">61
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">62
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">63
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">64
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">65
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">66
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f">67
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-css" data-lang="css"><span style="display:flex;"><span>:<span style="color:#a6e22e">root</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">/* you don’t really need to use `pf-font`, 
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">	if you don’t have a custom font.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">	for some reason, it wouldn’t render the font I specified here, 
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">	so I forced it with `!important` */</span>
</span></span><span style="display:flex;"><span>    --pf-font: your-font-name-here <span style="color:#75715e">!important</span>; 
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    --pf-text: <span style="color:#a6e22e">var</span>(<span style="color:#f92672">--</span>primary);
</span></span><span style="display:flex;"><span>    --pf-text-secondary: <span style="color:#a6e22e">var</span>(<span style="color:#f92672">--</span>secondary);
</span></span><span style="display:flex;"><span>    --pf-text-muted: <span style="color:#a6e22e">var</span>(<span style="color:#f92672">--</span>secondary);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    --pf-background: <span style="color:#a6e22e">var</span>(<span style="color:#f92672">--</span>theme);
</span></span><span style="display:flex;"><span>    --pf-border: <span style="color:#a6e22e">var</span>(<span style="color:#f92672">--</span>border);
</span></span><span style="display:flex;"><span>    --pf-border-focus: <span style="color:#a6e22e">var</span>(<span style="color:#f92672">--</span>primary);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    --pf-hover: <span style="color:#a6e22e">var</span>(<span style="color:#f92672">--</span>tertiary);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    --pf-mark: <span style="color:#a6e22e">var</span>(<span style="color:#f92672">--</span>primary);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    --pf-border-radius: <span style="color:#ae81ff">8</span><span style="color:#66d9ef">px</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    --pf-input-height: <span style="color:#ae81ff">48</span><span style="color:#66d9ef">px</span>;
</span></span><span style="display:flex;"><span>    --pf-input-font-size: <span style="color:#ae81ff">1</span><span style="color:#66d9ef">rem</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    --pf-result-title-font-size: <span style="color:#ae81ff">1</span><span style="color:#66d9ef">rem</span>;
</span></span><span style="display:flex;"><span>    --pf-result-excerpt-font-size: <span style="color:#ae81ff">0.90</span><span style="color:#66d9ef">rem</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    --pf-shadow-sm: <span style="color:#66d9ef">none</span>;
</span></span><span style="display:flex;"><span>    --pf-shadow-md: <span style="color:#66d9ef">none</span>;
</span></span><span style="display:flex;"><span>    --pf-shadow-lg: <span style="color:#66d9ef">none</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>.<span style="color:#a6e22e">search-content</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">margin-top</span>: <span style="color:#ae81ff">2</span><span style="color:#66d9ef">rem</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">pagefind-input</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">display</span>: <span style="color:#66d9ef">block</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">margin-bottom</span>: <span style="color:#ae81ff">1.5</span><span style="color:#66d9ef">rem</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">pagefind-summary</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">display</span>: <span style="color:#66d9ef">block</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">margin-bottom</span>: <span style="color:#ae81ff">1</span><span style="color:#66d9ef">rem</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">pagefind-results</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">display</span>: <span style="color:#66d9ef">block</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">margin-top</span>: <span style="color:#ae81ff">1</span><span style="color:#66d9ef">rem</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">pagefind-results</span> <span style="color:#f92672">a</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">text-decoration</span>: <span style="color:#66d9ef">none</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">pagefind-results</span> <span style="color:#f92672">article</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">border</span>: <span style="color:#ae81ff">1</span><span style="color:#66d9ef">px</span> <span style="color:#66d9ef">solid</span> <span style="color:#a6e22e">var</span>(<span style="color:#f92672">--</span>border);
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">border-radius</span>: <span style="color:#ae81ff">8</span><span style="color:#66d9ef">px</span>;
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">padding</span>: <span style="color:#ae81ff">1</span><span style="color:#66d9ef">rem</span>;
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">background</span>: <span style="color:#a6e22e">var</span>(<span style="color:#f92672">--</span>entry);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">pagefind-results</span> <span style="color:#f92672">article</span>:<span style="color:#a6e22e">hover</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">background</span>: <span style="color:#a6e22e">var</span>(<span style="color:#f92672">--</span>tertiary);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="5-make-search-work">5. Make Search Work.</h3>
<p>This is a 3 step process</p>
<h4 id="a-build-the-blog">a. Build the blog.</h4>
<p>Easy peasy. <code>hugo build</code> and we have our blog rendered in the <code>public</code> subdirectory.</p>
<h4 id="b-get-pagefind-to-create-its-index-in-the-build-directory">b. Get Pagefind to create its index in the build directory.</h4>
<p>This is easy as well.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>./tools/pagefind --site public
</span></span></code></pre></div><p>and Pagefind creates a <code>pagefind</code> subdirectory in our <code>public</code> directory where it creates its search index after reading all the html.<br>
All I need to do now, is just …</p>
<h4 id="c-publish">c. Publish!</h4>
<p>Ok, I lied a teensy bit. I don’t have to do <em>steps a.</em> and <em>b.</em> because they are part of <em>step c.</em><br>
The Forgejo action checks out my committed files, pulls in Hugo from a private package repo, builds the site, then runs Pagefind to generate the index<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> and finally uses rysnc to sync it with the VM. Here’s the relevant section of the action.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#75715e"># lots of stuff elided …</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">jobs</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">build-and-deploy</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">runs-on</span>: <span style="color:#ae81ff">my-big-box</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">env</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">HUGO_VERSION</span>: <span style="color:#ae81ff">${{ vars.HUGO_VERSION }}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">steps</span>: <span style="color:#75715e"># lots of snipped stuff …</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Checkout the website repo</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">uses</span>: <span style="color:#ae81ff">actions/checkout@v4</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">with</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">submodules</span>: <span style="color:#ae81ff">recursive</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">fetch-depth</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>      
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Build website with Hugo</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">env</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">HUGO_ENVIRONMENT</span>: <span style="color:#ae81ff">production</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">run</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          hugo \
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            --gc \
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            --minify</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Build the Pagefind search index</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">run</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          tools/pagefind \
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            --site public</span>
</span></span></code></pre></div><br>

<p>I thought the indexing would take a lot of time and was hesitant to use it as part of a regularly run Forgejo action workflow, but several runs show that the index generation only increases the time by at a couple of seconds at most. This is amazing!</p>
<p>Now I can search my own words, on my own blog, to my hearts content!</p>
<p><hr style='margin-left: auto; margin-right: auto; margin-bottom: 40px; margin-top: 50px; width:100px; border: none; background-color:rgb(238, 238, 238); color: rgb(238, 238, 238);  height: 1px;'/>

Feedback on this post?<br>
Mail me at <a href="mailto:feebdback@janusworx.com?subject=%22Feedback on post: You Can Now Search this Blog
%22">feedback at this domain</a>.
<br>

<br>

P.S. Subscribe to my <a href="https://janusworx.com/subscribe/">mailing list!</a></p>
<hr>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>as on 2026-06-23&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>this is why i chucked it into the tools subdirectory and committed it.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
  </channel>
</rss>
