<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>bimbo blog</title>
        <link>https://bimbo.nekoweb.org/</link>
        <description>a static site generator for dumb girls</description>
        <lastBuildDate>Tue, 23 Jun 2026 14:28:04 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <item>
            <title><![CDATA[intro to bimbo]]></title>
            <link>/posts/1-intro.html</link>
            <guid>/posts/1-intro.html</guid>
            <pubDate>Thu, 01 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[<a href="https://bsky.app/profile/iznaut.com/post/3lgqk46ddes2w"><img src="/images/bsky_post.png" alt="screenshot of the post that started it all"></a>]]></description>
            <content:encoded><![CDATA[<p><a href="https://bsky.app/profile/iznaut.com/post/3lgqk46ddes2w"><img src="/images/bsky_post.png" alt="screenshot of the post that started it all"></a></p>
<p>when i was in the 5th grade i got into making my own websites. mostly they were just simple pages where i proudly displayed my collection of Dragonball Z gifs i had downloaded, but that's not the point</p>
<p>the point is, if a 10 year old could make a website in the 90s, it should be even easier for an adult to make one in the 2020s…right?</p>
<p>i mean, yeah? kinda. not as easy as i would like tho. there's no shortage of paths you could take to create your own personal website, but i've recently had a difficult time choosing a path for <em>myself</em>, much less someone who hasn't been doing stuff like this since they were a child</p>
<p>so i made a <em>new</em> path.</p>
<p>a path for bimbos, <em>by</em> bimbos.</p>
<h1>static site generators</h1>
<p>bimbo is a &quot;static site generator&quot; - a tool that can help you build a website without having to do a lot of busy work (e.g. writing bespoke HTML for every page). there is no shortage of tools like this (and honestly, most of them are probably better than mine<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>), but they tend to assume you already know a lot about web development and have time to read a ton of documentation to use them</p>
<p>i somehow find myself in a weird space where i don't have enough time to learn any of these existing tools, but <em>did</em> have time to make my own. go figure.</p>
<p>the goal of bimbo is to be simple enough that you don't have to hold very much knowledge in your head to use it. you'll edit some files, let bimbo do its thing, and in seconds you'll have a complete website ready to be uploaded to a hosting service.</p>
<h1>files?</h1>
<p>yes, <em>files</em>. you will need to edit some text files for this.</p>
<p>bimbo is not a visual editor but it <em>does</em> come with its own web server that reloads automatically when you make changes.</p>
<p>i promise it's not <em>that</em> bad.</p>
<p><img src="/images/dbz_goku.gif" alt="classic animated gif of Goku from Dragonball Z"></p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>i've personally used <a href="https://www.11ty.dev/">Eleventy (11ty)</a> before and it seems nice. if you wanted something more mature/advanced, that's probably what i would recommend (along with the <a href="https://strawberrystarter.neocities.org/">Strawberry Starter</a> template) <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[getting started]]></title>
            <link>/posts/2-getting-started.html</link>
            <guid>/posts/2-getting-started.html</guid>
            <pubDate>Fri, 02 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[you can download bimbo from itch.io. i've personally tested the Mac<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> one quite a lot, but the Windows one should work fine. after extracting the zip file and running the bimbo executable (.app or .exe), you should find a sparkling heart emoji icon in your system task/status bar.]]></description>
            <content:encoded><![CDATA[<p>you can download bimbo from itch.io. i've personally tested the Mac<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> one quite a lot, but the Windows one should work fine. after extracting the zip file and running the bimbo executable (.app or .exe), you should find a sparkling heart emoji icon in your system task/status bar.</p>
<p><img src="/images/tray_mac.png" alt="bimbo tray icon on Mac">
<img src="/images/tray_win.png" alt="bimbo tray icon on Windows"></p>
<p>you can open the bimbo menu by left (on Mac)/right (on Windows) clicking this icon, which should look something like this if it's your first time:</p>
<p><img src="/images/create_project_menu.png" alt="bimbo tray icon on Windows"></p>
<p>select <code>create new project &gt; minimal</code> and select a folder to create the <code>minimal</code> project in. bimbo will automatically load the new project, which you'll see when opening the menu again:</p>
<p><img src="/images/preview_menu.png" alt="bimbo tray icon on Windows"></p>
<p>select <code>preview in browser</code> and watch in amazement as a real live<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> webpage appears in your default web browser</p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>specifically, the Apple Silicon version, which you can use if you have a newer device using their M-series of processors. if you're not sure, you can try using the Intel one <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>but not like <em>live</em> live - <code>localhost</code> refers to the device you're running bimbo on and <code>6969</code> (nice, nice) is the network port it's available on. this address will only work while bimbo is running and is only for <em>previewing</em> your site. we'll talk about deploying to the greater internet later <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[the basics]]></title>
            <link>/posts/3-basics.html</link>
            <guid>/posts/3-basics.html</guid>
            <pubDate>Sat, 03 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[now that you've successfully initialized a new bimbo project and learned how to preview it, we can start talking about the editing process. i've tried to make bimbo's project structure as straight-forward as possible (something that most SSGs just can't seem to accomplish for some reason)<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> but i'm always <a href="mailto:bimbo@iznaut.com">open to feedback</a> on how i can do better]]></description>
            <content:encoded><![CDATA[<p>now that you've successfully initialized a new bimbo project and learned how to preview it, we can start talking about the editing process. i've tried to make bimbo's project structure as straight-forward as possible (something that most SSGs just can't seem to accomplish for some reason)<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> but i'm always <a href="mailto:bimbo@iznaut.com">open to feedback</a> on how i can do better</p>
<p>if you open the bimbo menu and select <code>open project folder</code>, you'll find the following folders:</p>
<h1>content</h1>
<p><code>/content</code> is where most ppl will spend the bulk of their time. anything you write in here will appear on your website for all the world to see</p>
<p>bimbo expects to find <code>.md</code> (Markdown) files in this folder, which will be converted into <code>.html</code> files on build.</p>
<h1>templates</h1>
<p><code>/templates</code> is the next layer up in a sense - since you can't do very advanced formatting with Markdown, you'll likely want a bit of raw HTML in the mix.</p>
<p>any <code>.html</code> files in this folder can be used as a base, with your content and other unique data being piped in at build time - no need to copy/paste stuff!</p>
<p><code>/templates/partials</code> contains <code>.hbs</code> (Handlebars) files - we'll go into more detail about these later, but they're basically smaller templates that can be nested within the larger ones.</p>
<p>a simple example is the navigation bar at the top of this page - we want it everywhere, so it's included as a &quot;partial&quot; on each page template.</p>
<h1>static</h1>
<p><code>/static</code> is where you keep things that you want copied over 1:1 when the site is built.</p>
<p>a good example of this might be some image files or CSS/JavaScript that doesn't require any processing through bimbo</p>
<h1>_site</h1>
<p>finally, <code>/_site</code> is where bimbo will output everything. this is the fully generated site that will be uploaded to your webhost!</p>
<p>you could totally do any editing of these files in Notepad or something simple like that, but i recommend downloading <a href="https://vscodium.com">VS Codium</a><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> for a nicer experience. if installed, you can select the <code>edit in VS Codium</code> menu option to quickly open your project folder in the editor</p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>when in doubt, make frequent use of the &quot;Find in Files&quot; shortcut (Cmd/Ctrl+Shift+F), which can be super helpful when you're trying to understand how everything fits together <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>VS Codium is an alternative version of Microsoft's Visual Studio Code that disables telemetry/tracking. They aren't functionally much different (though some extensions are not available in the &quot;open&quot; marketplace), but VS Codium feels like the <a href="https://bdsmovement.net/microsoft">more moral option</a> imo. <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[metadata and config]]></title>
            <link>/posts/4-config.html</link>
            <guid>/posts/4-config.html</guid>
            <pubDate>Sun, 04 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[in addition to injecting your content into the relevant templates, bimbo also checks a handful of locations for metadata values. this metadata is compiled into a single "dictionary" object that can be referenced during the build process, allowing matching "keys" in your templates to be dynamically replaced with data you've supplied.]]></description>
            <content:encoded><![CDATA[<p>in addition to injecting your content into the relevant templates, bimbo also checks a handful of locations for metadata values. this metadata is compiled into a single &quot;dictionary&quot; object that can be referenced during the build process, allowing matching &quot;keys&quot; in your templates to be dynamically replaced with data you've supplied.</p>
<p>let's look at some of the options you have for defining data:</p>
<h1>bimbo.yaml</h1>
<p><code>bimbo.yaml</code> acts as a &quot;global&quot; configuration file that all pages have access to. for example, you may notice the footer on this page includes the title of this blog and my name. if i wanted to include the title elsewhere, i could use this placeholder in a <code>.html</code> or <code>.hbs</code> file:</p>
<p><code>{{site.title}}</code></p>
<p>this placeholder matches a key in <code>bimbo.yaml</code>:</p>
<pre><code class="hljs"><span class="hljs-symbol">site:</span>
<span class="hljs-symbol">  title:</span> bimbo blog
</code></pre>
<p>so <code>{{site.title}}</code> will be replaced with &quot;bimbo blog&quot; when the site is rebuilt.</p>
<h1>content &quot;front matter&quot;</h1>
<p>you can also include key/value pairs directly inside your content <code>.md</code> files - using this post as example:</p>
<pre><code class="hljs"><span class="hljs-meta">---</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">metadata</span> <span class="hljs-string">and</span> <span class="hljs-string">config</span>
<span class="hljs-attr">date:</span> <span class="hljs-number">2026-01-04</span>
<span class="hljs-attr">draft:</span> <span class="hljs-literal">false</span>
<span class="hljs-meta">---
</span></code></pre>
<p>this is called &quot;front matter&quot;</p>
<p>as you might guess, the <code>title</code> and <code>date</code> values are pulled into the <code>post.html</code> template used to generate this page.</p>
<p>the <code>draft</code> value is a bit special - if bimbo sees tha this value is <code>true</code>, it will skip it during the build process.</p>
<h1>defaults and overrides</h1>
<p>if you'd like to apply some default metadata to your content files, you can do so globally by setting the <code>contentDefaults</code> in <code>bimbo.yaml</code>.</p>
<p>if you'd like to only apply defaults to a subset of your content, you can create a <code>~default.yaml</code> file in a folder, which will affect only <code>.md</code> files in that directory.</p>
<p>bimbo will ultimately use whatever values are most specific (global &gt; local to folder &gt; front matter) when generating a page.</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[hosting your website]]></title>
            <link>/posts/5-deploy.html</link>
            <guid>/posts/5-deploy.html</guid>
            <pubDate>Mon, 05 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[once you're happy with the local preview of your website, it's time to upload the contents of <code>/_site</code> to the internet for the world to see.]]></description>
            <content:encoded><![CDATA[<p>once you're happy with the local preview of your website, it's time to upload the contents of <code>/_site</code> to the internet for the world to see.</p>
<p>this process varies slightly depending on which hosting service you use, so i won't go into great detail here. i will say that <a href="https://neocities.org/">Neocities</a> seems to be the one i hear about most commonly. personally, i've been trying out <a href="https://nekoweb.org/">Nekoweb</a>, and liking it so far.</p>
<h1>one-click deploy</h1>
<p>if you pay the minimum price for bimbo, you can access bimbo+<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> which has a &quot;one-click deploy&quot; feature. you can enable this by selecting your provider of choice from the <code>set up deployment</code> menu. bimbo currently supports Neocities and Nekoweb via API, but you can use any hosting service that supports SFTP (Secure File Transfer Protocol) by selecting the <code>other</code> option.</p>
<p>upon selecting one of these options, a window will pop up and ask for some information that will be saved in <code>bimbo-secrets.yaml</code><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup>. after adding this configuration, you should now see an option to deploy to your provider in the menu.</p>
<p>you can always edit <code>bimbo-secrets.yaml</code> later or delete it entirely to restore the <code>set up deployment</code> option if you want to use a different provider.</p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>feels rude to paywall like this, but i've also sunk a lot of hours into this project at this point and it would be nice to get some small return on the investment. i figure if you're doing enough work with bimbo that manual uploading becomes an inconvenience, you probably like the tool enough to make a one-time contribution <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>technically, you could put this stuff in <code>bimbo.yaml</code> as well, but <code>bimbo-secrets.yaml</code> is ideal for sensitive configuration that you don't want to include in version control<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup> (like API keys) <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn3" class="footnote-item"><p>version control is another can of worms entirely. i DO recommend it for your projects and should note that new projects will automatically include a <code>.gitignore</code> file that keeps <code>/_site</code> and <code>bimbo-secrets.yaml</code> from being included in git commits <a href="#fnref3" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[the advanced]]></title>
            <link>/posts/6-advanced.html</link>
            <guid>/posts/6-advanced.html</guid>
            <pubDate>Tue, 06 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[by now you've hopefully have a rough idea of how a bimbo project works and how to work with it. this post goes a bit more into the weeds of working with <a href="https://handlebarsjs.com/">Handlebars</a>]]></description>
            <content:encoded><![CDATA[<p>by now you've hopefully have a rough idea of how a bimbo project works and how to work with it. this post goes a bit more into the weeds of working with <a href="https://handlebarsjs.com/">Handlebars</a></p>
<h1>templating deep dive</h1>
<p>let's look at <code>/templates/archive.html</code>:</p>
<pre><code class="hljs"><span class="language-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
</span><span class="hljs-template-variable">{{&gt; <span class="hljs-name">head</span>}}</span><span class="language-xml">

<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;container&quot;</span>&gt;</span>
        </span><span class="hljs-template-variable">{{&gt; <span class="hljs-name">navbar</span>}}</span><span class="language-xml">
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;content&quot;</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span></span><span class="hljs-template-variable">{{<span class="hljs-name">title</span>}}</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            </span><span class="hljs-template-variable">{{{<span class="hljs-name">content</span>}}}</span><span class="language-xml">
            </span><span class="hljs-template-variable">{{&gt; <span class="hljs-name">post-list</span>}}</span><span class="language-xml">
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        </span><span class="hljs-template-variable">{{&gt; <span class="hljs-name">footer</span>}}</span><span class="language-xml">
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</span></code></pre>
<p>these double bracket placeholders that appear all over the template files are Handlebars expressions. a simple example here is the <code>{{title}}</code> expression, which gets replaced on build with the <code>title</code> value defined in <code>archive.md</code>.</p>
<p>by default, Handlebars will &quot;escape&quot; values returned by an expression. if you don't want this, you can add a third set of brackets to return the &quot;raw&quot; value instead (as is the case with the <code>{{{content}}}</code> expression, which is the Markdown body of <code>archive.md</code> converted into HTML)</p>
<p>the last thing i'd like to point out in this template is the use of <code>&gt;</code> - this is where the <code>.hbs</code> files in <code>/templates/partials</code> come in. instead of piping data in, these expressions will be expanded into HTML &quot;partials&quot;. let's look more closely at <code>/templates/partials/post-list.hbs</code>, which will replace <code>{{&gt; post-list}}</code>:</p>
<pre><code class="hljs"><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;postlistdiv&quot;</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        </span><span class="hljs-template-tag">{{#<span class="hljs-name"><span class="hljs-built_in">each</span></span> site.blogPosts}}</span><span class="language-xml">
            <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;</span></span></span><span class="hljs-template-variable">{{<span class="hljs-name">this.url</span>}}</span><span class="language-xml"><span class="hljs-tag"><span class="hljs-string">&quot;</span>&gt;</span></span><span class="hljs-template-variable">{{<span class="hljs-name">formatDate</span> this.date}}</span><span class="language-xml"> » </span><span class="hljs-template-variable">{{<span class="hljs-name">this.title</span>}}</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        </span><span class="hljs-template-tag">{{/<span class="hljs-name"><span class="hljs-built_in">each</span></span>}}</span><span class="language-xml">
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</span></code></pre>
<p>here we have some more unique Handlebars syntax. let's talk about <code>#each</code> first, which accepts an array (in this case, <code>site.blogPosts</code>) as an parameter. the HTML inside the <code>#each</code> block will be rendered once per item in this array, which we can access using the <code>this</code> variable.</p>
<p>the end result is a bulleted list of dates and titles, which link to the actual posts themselves. there's a bit of bimbo specific<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> junk<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> happening here that isn't super important, but hopefully it mostly makes sense!</p>
<p>i'd recommend checking out the <a href="https://handlebarsjs.com/guide/#simple-expressions">Handlebars documentation</a> to learn more about this syntax and what kinds of things you can do with it</p>
<h1>working with <code>/data</code></h1>
<p>in addition to all the folders we covered in an earlier post, you can also create a <code>/data</code> folder to load in a handful of non-Markdown formats such as '.json' and '.yaml'. these can be accessed in templates via the special <code>site.userDefined</code> variable.</p>
<p>for a simple example, let's imagine we have a <code>/data/colors.txt</code> file that contains the following:</p>
<pre><code class="hljs"><span class="hljs-built_in">Red</span>
<span class="hljs-built_in">Green</span>
<span class="hljs-built_in">Blue</span>
</code></pre>
<p>this list will automatically be split into an array that can then be iterated over:</p>
<pre><code class="hljs"><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    </span><span class="hljs-template-tag">{{#<span class="hljs-name"><span class="hljs-built_in">each</span></span> site.userDefined.colors}}</span><span class="language-xml">
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span></span><span class="hljs-template-variable">{{<span class="hljs-name">this</span>}}</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    </span><span class="hljs-template-tag">{{/<span class="hljs-name"><span class="hljs-built_in">each</span></span>}}</span><span class="language-xml">
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</span></code></pre>
<p>which will be compiled into the following:</p>
<pre><code class="hljs">&lt;<span class="hljs-selector-tag">ul</span>&gt;
    &lt;<span class="hljs-selector-tag">li</span>&gt;Red/<span class="hljs-selector-tag">li</span>&gt;
    &lt;<span class="hljs-selector-tag">li</span>&gt;Green/<span class="hljs-selector-tag">li</span>&gt;
    &lt;<span class="hljs-selector-tag">li</span>&gt;Blue/<span class="hljs-selector-tag">li</span>&gt;
&lt;/<span class="hljs-selector-tag">ul</span>&gt;
</code></pre>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p><code>site.blogPosts</code> is kind of a &quot;magic&quot; variable in that it's not something you define anywhere - it's created dynamically during the build process. i don't love this and would like to find a better way of handling things like this that isn't so opaque or at least document it better <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p><code>formatDate</code> is a custom function inside bimbo that does exactly what it says. you can adjust the actual formatting by editing the <code>site.dateFormat</code> value in <code>bimbo.yaml</code> <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[blog comments with Bluesky]]></title>
            <link>/posts/7-bsky-comments.html</link>
            <guid>/posts/7-bsky-comments.html</guid>
            <pubDate>Wed, 07 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[when you have a blog, it's nice for your readers to have a space where they can share their thoughts<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> and connect with you. there are various options available for allowing this (<a href="https://disqus.com/">Disqus</a> being the one i hear about the most), but we like to keep it sleezy here at bimbo so i'm taking a different tact]]></description>
            <content:encoded><![CDATA[<p>when you have a blog, it's nice for your readers to have a space where they can share their thoughts<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> and connect with you. there are various options available for allowing this (<a href="https://disqus.com/">Disqus</a> being the one i hear about the most), but we like to keep it sleezy here at bimbo so i'm taking a different tact</p>
<h1>Bluesky</h1>
<p>if you found this place, you <em>probably</em> know what Bluesky is bc i have been posting about bimbo on there. if you don't, it's a social media site like Twitter<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> but with some futuristic tech stuff going on in the background that i don't really care to explain, BUT the important part for our purposes is that you can pretty easily use their API<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup> to grab data and do cool stuff with it on your website</p>
<p>thanks to <a href="https://capscollective.com/blog/bluesky-blog-comments/">this post from Jonathan Moallem of Caps Collective</a>, it was trivially easy to just kind of drop-in support for &quot;comments&quot; via Bluesky posts. the idea is that you can make a post on Bluesky linking to your blog post and any replies to that will be displayed on the actual webpage of your blog post.</p>
<p>the advantage of this approach is that it captures a lot of the conversation folks are already having in response to your Bluesky post (rather than splintering it with a bespoke commenting platform), it allows you to leverage Bluesky's moderation tools (blocking users on Bluesky will also hide their posts on your blog), and maybe most importantly (to me, anyway) - it doesn't require someone to sign up for another service (assuming they're already on Bluesky, obviously)</p>
<h1>adding comments with bimbo</h1>
<p>since this is something i'm personally interested in leveraging for my blog, i decided to make it a Proper Feature in bimbo rather than just hacking it in<sup class="footnote-ref"><a href="#fn3" id="fnref3:1">[3:1]</a></sup>. i think it's about as straightforward as it can be (without a lot of extra work on my end, anyway), but as always, please let me know<sup class="footnote-ref"><a href="#fn4" id="fnref4">[4]</a></sup> if you have suggestions on how to improve this functionality</p>
<p>also - i suppose it's worth saying that i assume you're using the latest version of bimbo and a fresh project (initialized from the latest <code>example.zip</code>) for this to work.</p>
<p>first off, you'll want to open <code>bimbo.yaml</code> and edit the value under <code>site.integrations.bskyUserId</code>:</p>
<pre><code class="hljs">  ...
  <span class="hljs-params">sortPostsAscending:</span> <span class="hljs-literal">true</span>
  <span class="hljs-params">codeTheme:</span> tokyo-night-dark
  <span class="hljs-params">integrations:</span>
    <span class="hljs-params">bskyUserId:</span> sofkq7uzgyczeyl24wxuc47o
</code></pre>
<p>the existing user ID is for an account i made just for this demo site, which is <a href="https://bsky.app/profile/bimbo.nekoweb.org">@bimbo.nekoweb.org</a><sup class="footnote-ref"><a href="#fn5" id="fnref5">[5]</a></sup>. the other important bit of config will be on the blog post itself, as we can see here on <code>7-bsky-comments.md</code>:</p>
<pre><code class="hljs"><span class="hljs-meta">---</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">comments</span> <span class="hljs-string">with</span> <span class="hljs-string">Bluesky</span>
<span class="hljs-attr">date:</span> <span class="hljs-number">2025-02-07</span>
<span class="hljs-attr">draft:</span> <span class="hljs-literal">false</span>
<span class="hljs-attr">bskyPostId:</span> <span class="hljs-string">3lincp4ikhe2c</span>
<span class="hljs-meta">---
</span></code></pre>
<p>so now you know my Bluesky user ID and the ID of the specific post that we want to display comments from. but how do you get these for <em>your</em> blog?</p>
<p>it's not pretty, but you'll want to open the elipsis (...) menu on the Bluesky post in question and click &quot;Embed post&quot;. here's what i get when i copy this code:</p>
<pre><code class="hljs"><span class="hljs-tag">&lt;<span class="hljs-name">blockquote</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;bluesky-embed&quot;</span> <span class="hljs-attr">data-bluesky-uri</span>=<span class="hljs-string">&quot;at://did:plc:sofkq7uzgyczeyl24wxuc47o/app.bsky.feed.post/3lincp4ikhe2c&quot;</span> <span class="hljs-attr">data-bluesky-cid</span>=<span class="hljs-string">&quot;bafyreibm7nkc6sa5xs47du7x4ogdxiyqkbwykh62s6s4o32v6wkdddowcq&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">&quot;en&quot;</span>&gt;</span>this is a post to test comments on bimbo blog!<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><span class="hljs-symbol">&amp;mdash;</span> bimbo.nekoweb.org (<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;https://bsky.app/profile/did:plc:sofkq7uzgyczeyl24wxuc47o?ref_src=embed&quot;</span>&gt;</span>@bimbo.nekoweb.org<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>) <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;https://bsky.app/profile/did:plc:sofkq7uzgyczeyl24wxuc47o/post/3lincp4ikhe2c?ref_src=embed&quot;</span>&gt;</span>February 20, 2025 at 4:12 PM<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">blockquote</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">async</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;https://embed.bsky.app/static/embed.js&quot;</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;utf-8&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<p>see the <code>data-bluesky-url</code> value? let's look at that more closely:</p>
<pre><code class="hljs"><span class="hljs-attribute">data-bluesky-uri</span><span class="hljs-operator">=</span><span class="hljs-string">&quot;at://did:plc:sofkq7uzgyczeyl24wxuc47o/app.bsky.feed.post/3lincp4ikhe2c&quot;</span>
</code></pre>
<p>it's still ugly, but you can hopefully see now where these IDs are coming from: the user is just after the <code>at://did:plc:</code> bit and the post is after that final slash. these are the values you'll want to copy out and place in their respective locations<sup class="footnote-ref"><a href="#fn6" id="fnref6">[6]</a></sup></p>
<h1>that's it?</h1>
<p>that's it! your post should now have some indication of being connected to Bluesky at the bottom. i should also note - if you don't include a <code>bskyPostId</code> on a post, it simply won't show any of this junk. so it's totally opt-in.</p>
<h2>bonus feature: icons</h2>
<p>this is not <em>really</em> relevant to all this comments stuff but you may also notice that there are icons alongside your reply/repost/like counts - the latest bimbo has a new Handlebars helper function that allows you to quickly add icons in your templates via <a href="https://feathericons.com/">Feather</a></p>
<p>if you want to icons elsewhere on your site, i recommend checking out <code>templates/partials/bsky-comments.hbs</code> to see how i'm implementing them. have fun!</p>
<hr class="footnotes-sep">
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item"><p>i mean, in theory. let's be optimistic about the things ppl might have to say on the internet, just for the sake of this post <a href="#fnref1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn2" class="footnote-item"><p>i am not optimistic that you would want to hear the things ppl might have to say on Twitter at this point, tbh <a href="#fnref2" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn3" class="footnote-item"><p>tbf about 90% of this project is me just &quot;hacking it in&quot;. i guess the real difference is that i'm writing a tutorial for how to use it? <a href="#fnref3" class="footnote-backref">↩︎</a> <a href="#fnref3:1" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn4" class="footnote-item"><p>via the comments at the bottom of this page, perhaps? <a href="#fnref4" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn5" class="footnote-item"><p>you don't have to make a new account just for this purpose, but it is kinda cool to have a user handle that points at your blog's domain <a href="#fnref5" class="footnote-backref">↩︎</a></p>
</li>
<li id="fn6" class="footnote-item"><p>the user ID will be referenced globally from <code>bimbo.yaml</code>, so this should be the only time you have to set it. the post ID will likely be unique per blog post, though <a href="#fnref6" class="footnote-backref">↩︎</a></p>
</li>
</ol>
</section>
]]></content:encoded>
        </item>
    </channel>
</rss>