<?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>bhread on Bhread blog</title><link>https://blog.bhread.com/tags/bhread/</link><description>Recent content in bhread on Bhread blog</description><image><title>Bhread blog</title><url>https://blog.bhread.com/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</url><link>https://blog.bhread.com/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</link></image><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 12 Feb 2024 20:12:03 +0800</lastBuildDate><atom:link href="https://blog.bhread.com/tags/bhread/index.xml" rel="self" type="application/rss+xml"/><item><title>Protocol Live</title><link>https://blog.bhread.com/posts/protocol-live/</link><pubDate>Mon, 12 Feb 2024 20:12:03 +0800</pubDate><guid>https://blog.bhread.com/posts/protocol-live/</guid><description>The new version of Bhread is now live!</description><content:encoded><![CDATA[<p>replying to <a href="https://blog.bhread.com/posts/my-first-post/">https://blog.bhread.com/posts/my-first-post/</a></p>
<p>The new version of <a href="https://bhread.com">Bhread</a> is now live!</p>
<p>It took me 4 months to complete this. It took longer than expected because of the holidays and my day job.</p>
<p>We have implemented replies, votes, reposts, and groups. The group feature is not well-implemented and not tested at all, so things will change!</p>
<p>In the future, I plan to implement the per-site comment section feature.</p>
]]></content:encoded></item><item><title>Lazy Loading with HTMX</title><link>https://blog.bhread.com/posts/lazy-loading/</link><pubDate>Sun, 24 Sep 2023 10:57:40 +0800</pubDate><guid>https://blog.bhread.com/posts/lazy-loading/</guid><description>Introducing lazy loading of posts in bhread&amp;#39;s home page.</description><content:encoded><![CDATA[<p>Bhread now lazy loads posts!</p>
<h2 id="what-is-lazy-loading">What is lazy loading?</h2>
<blockquote>
<p>Lazy loading is a technique for waiting to load certain parts of a webpage — especially images — until they are needed.
<a href="https://www.cloudflare.com/learning/performance/what-is-lazy-loading/">source</a></p>
</blockquote>
<p>Visiting bhread.com will show 6 posts. If you reach the bottom of the page, it will load 8 more. The process repeats until
no more posts are found. This is also known as infinite scrolling.</p>
<h2 id="why-lazy-load-posts">Why lazy load posts?</h2>
<p><img loading="lazy" src="/images/lazy-loading-110kb.png" alt="lazy-loading-110kb"  />
</p>
<p>Bhread.com loads a 100kb file when the home page is visited. This was because at the time of testing, the total numer of posts is around 30.
It loads all 30 of them in a single visit. This is a waste of bandwidth as most of the time, the user won&rsquo;t scroll far down anyway.</p>
<p>The 100kb file takes a long time to load (~1sec).</p>
<p>Now, it loads a 26kb file (still a bit big) in 350milsec. This is a big improvement in useability. It&rsquo;s the difference between snappy and sluggish.</p>
<p><img loading="lazy" src="/images/lazy-loading-26kb.png" alt="lazy-loading-26kb"  />
</p>
<h3 id="still-supports-no-javascript">Still supports no javascript</h3>
<p><img loading="lazy" src="/images/lazy-loading-nojs-alt.png" alt="lazy-loading-nojs-alt"  />
</p>
<p>Don&rsquo;t have javascript? You&rsquo;re still covered! Bhread will display a &lsquo;Next page&rsquo; link so users without js can still use Bhread.</p>
<h2 id="how">How?</h2>
<p>With HTMX, it&rsquo;s pretty easy.</p>
<p>First, send the user a list containing a list item with htmx:</p>
<p><code>/home</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ol</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=1}} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=2}} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=3}} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=4}} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span> <span class="na">hx-get</span><span class="o">=</span><span class="s">&#34;/htmx-home?id=4&#34;</span> <span class="na">hx-trigger</span><span class="o">=</span><span class="s">&#34;intersect once&#34;</span> <span class="na">hx-swap</span><span class="o">=</span><span class="s">&#34;outerHTML&#34;</span> <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        {{ post-loading-skeleton }} 
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">ol</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>What this does: render posts 1-4, then issue a get request to /htmx-home when the last element is seen by the user (intersect). Send the id of the last post.
If a response is received, replace THIS item  (li) with the new items.</p>
<p>Then, /htmx-home receives the id and returns the new posts which follow the id of the last post.</p>
<p><code>/htmx-home?id=4</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=5 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=6 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=7 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=8 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">li</span> <span class="na">hx-get</span><span class="o">=</span><span class="s">&#34;/htmx-home?id=8&#34;</span> <span class="na">hx-trigger</span><span class="o">=</span><span class="s">&#34;intersect once&#34;</span> <span class="na">hx-swap</span><span class="o">=</span><span class="s">&#34;outerHTML&#34;</span> <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    {{ post-loading-skeleton }} 
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>The resulting html is this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">ol</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=1 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=2 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=3 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=4 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=5 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=6 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=7 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span> {{ post id=8 }} <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span> <span class="na">hx-get</span><span class="o">=</span><span class="s">&#34;/htmx-home?id=8&#34;</span> <span class="na">hx-trigger</span><span class="o">=</span><span class="s">&#34;intersect once&#34;</span> <span class="na">hx-swap</span><span class="o">=</span><span class="s">&#34;outerHTML&#34;</span> <span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">        {{ post-loading-skeleton }} 
</span></span><span class="line"><span class="cl">    <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">ol</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>The process continues until no more posts are found.</p>
<h2 id="how-about-nojs">How about noJS?</h2>
<p>The good thing about HTMX is that it allows the site to degrade well when JS is disabled. It&rsquo;s a bit more complicated to implement but I expect Bhread to deal with mostly static sites. Ones that don&rsquo;t need JS to function. So I think it&rsquo;s worth the effort to implement this. Your mileage may vary.</p>
<p>To outline how this is implemented, here&rsquo;s a rough step-by-step:</p>
<ul>
<li>In the backend, detect if request is coming with an HTMX request header. If not present, the user has JS disabled.</li>
<li>In the frontend, add a <code>&lt;noscript&gt;</code> tag that includes a button labeled &rsquo;next&rsquo;. This button should include the ID of the last item that was rendered.</li>
<li>When generating the html, check if JS is enabled in the request.</li>
<li>If yes, add the htmx-enabled element that will request for new items when seen</li>
<li>If not, don&rsquo;t add anything.</li>
<li>The <code>&lt;noscript&gt;</code> element will still be present whether JS is on or not. We don&rsquo;t need to worry about this because it takes advantage of the fact that this block will not be shown unless JS is disabled.</li>
<li>Now make both <code>/home</code> and <code>/htmx-home</code> accept an ID argument which is the ID of the last element rendered.</li>
<li>If JS is enabled, use the route for htmx: <code>/htmx-home</code>, passing the ID and returning a new list of partials that continues from the ID</li>
<li>The client receives this and appends it to the current list of items.</li>
<li>If JS is disabled, use the normal route for the home page <code>/home</code>, passing the ID and returning a new page containing the new items that follow the ID.</li>
<li>When the button for &rsquo;next page&rsquo; is pressed, the page will reload containing the new posts and another &rsquo;next page&rsquo; button.</li>
</ul>
<p>If you&rsquo;re interested in this, the code is FOSS, the backend code for this is here:</p>
<p><a href="https://github.com/elpachongco/bhread/blob/main/bhread/feed/views.py#L24">views.py</a></p>
<p>and the HTML template is here:</p>
<p><a href="https://github.com/elpachongco/bhread/blob/main/bhread/feed/templates/feed/home.html#L30">home.html</a></p>
<h2 id="stay-updated">Stay updated</h2>
<p>For more updates, subscribe to the <a href="https://blog.bhread.com/index.xml">bhread blog&rsquo;s RSS feed</a>, visit <a href="https://bhread.com">Bhread.com</a> or <a href="https://blog.bhread.com/posts/bhread-discord-server/">join the discord server</a>.</p>
]]></content:encoded></item><item><title>About Bhread</title><link>https://blog.bhread.com/posts/about-bhread/</link><pubDate>Wed, 20 Sep 2023 18:52:29 +0800</pubDate><guid>https://blog.bhread.com/posts/about-bhread/</guid><description>What is bhread, why create bhread</description><content:encoded><![CDATA[<h2 id="welcome-to-bhreadcom">Welcome to Bhread.com!</h2>
<p><a href="https://bhread.com">Bhread.com</a> is a platform that makes threads out of blogs.</p>
<p>To get started, you need:</p>
<ul>
<li>A blog with an RSS or Atom Feed</li>
</ul>
<p>Register an account on <a href="https://bhread.com/accounts/signup/">bhread.com</a> and add a feed. Follow the instructions on the feed creation page.</p>
<p>After registration and verification, bhread will (politely) scan your feed every 2 minutes. If it finds a post starting with &lsquo;replying to <!-- raw HTML omitted -->&rsquo;, it will make a
thread from it. That&rsquo;s it!</p>
<h2 id="idea">Idea</h2>
<p>The idea of bhread is to create a centralized hub of interactions without centralizing data.</p>
<h3 id="the-absolute-state-of-internet-content">The absolute state of internet content</h3>
<p>When I search for something today, I usually use <code>site:reddit.com</code> to find something valuable. For example I google: <code>best anime 2023 site:reddit.com</code>.</p>
<p>This makes google output results from <code>reddit.com</code>. I do this because most of the helpful content is on reddit.
Otherwise, I&rsquo;ll get results from SEO-optimized sites which usually don&rsquo;t have useful content.</p>
<p>Reddit, Facebook, Twitter and other social media platforms contain very important knowledge.
And It&rsquo;s important to protect it and to allow it to be accessible to every user of the internet.</p>
<p>Unfortunately these sites only allow access if you have an account. Facebook doesn&rsquo;t allow search engines to crawl their site.</p>
<p>It&rsquo;s unfortunate because some of the most active and knowledgeable groups I found on the internet is on Facebook.</p>
<p>It&rsquo;s unthinkable how much knowledge must be inside their <a href="https://en.wikipedia.org/wiki/Closed_platform">walled gardens</a>.</p>
<p>This is inefficient and it&rsquo;s not how the internet should be. Humanity&rsquo;s knowledge should not belong to these entities who at a whim, can just
<a href="https://en.wikipedia.org/wiki/2023_Reddit_API_controversy">close</a>
<a href="https://techcrunch.com/2023/06/30/twitter-now-requires-an-account-to-view-tweets/">down</a>
their platform and do anything with their user&rsquo;s data.</p>
<h3 id="its-unusual-to-have-a-blog-but-everyone-has-a-facebook-reddit-and-twitter-account">It&rsquo;s unusual to have a blog but everyone has a facebook, reddit, and twitter account</h3>
<p>Why are we using these platforms instead of creating blogs?</p>
<p>Well</p>
<ul>
<li>Blogs aren&rsquo;t interactive, twitter allows you to reply, like, and retweet a post.</li>
<li>Blogs are harder to discover, facebook connects you to everyone you know.</li>
<li>Blogs are harder to setup, reddit just needs your username, email and password.</li>
</ul>
<p>Blogs are outlets for personal expresssion. But where do you go if you want to see content from other people?</p>
<p>These social media platforms are attractive because they allow hassle-free interactions, and discoverability.</p>
<h3 id="so-why-create-bhread">So why create Bhread?</h3>
<p>Bhread was created because I want to bring the same interactions as facebook, reddit, twitter to blogs.</p>
<p>Bhread allows users to post, and reply using their blogs (which they fully own).</p>
<p>With replies, tagging (wip), and groups (wip) we can create a more fun blogging experience.</p>
<p>Bhread is designed so that if the bhread website dies, everyone still has their content. Anyone who replaces bhread can easily replicate its previous state.
No one will be able to control every person&rsquo;s blogs. It will be indestructible.</p>
<h3 id="ok-so-how-do-we-do-this">OK, so how do we do this?</h3>
<p>Help me achieve the dream of a more open internet. Register your blog today on <a href="https://bhread.com/accounts/signup/">bhread.com</a>.</p>
<p>If you don&rsquo;t have a blog, create one for yourself and have your own slice of the internet.</p>
<p>TLDR:
<img loading="lazy" src="img/about-bhread-meme.png" alt="Meme showing a house on fire and a cartoon character inside saying &amp;rsquo;this is fine&amp;rsquo;"  />
</p>
]]></content:encoded></item></channel></rss>