<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Website Changelog on Kaveen Rodrigo</title><link>https://ukr.lk/series/website-changelog/</link><description>Recent content in Website Changelog on Kaveen Rodrigo</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 25 Aug 2026 00:00:00 +0530</lastBuildDate><atom:link href="https://ukr.lk/series/website-changelog/index.xml" rel="self" type="application/rss+xml"/><item><title>New pages, photos and other oddities</title><link>https://ukr.lk/posts/website-update-aug-2026/</link><pubDate>Tue, 25 Aug 2026 00:00:00 +0530</pubDate><guid>https://ukr.lk/posts/website-update-aug-2026/</guid><description>&lt;p&gt;To my two followers, here&amp;rsquo;s an update on the site. Leave the comforts of your RSS readers and checkout what I&amp;rsquo;ve done here.&lt;/p&gt;
&lt;h2 id="inspirations"&gt;Inspirations&lt;/h2&gt;
&lt;p&gt;Couple of weeks back, my desire to make the site better was rekindled, after seeing &lt;a href="https://thamara.co.uk/"&gt;Thamara&amp;rsquo;s website&lt;/a&gt;.
Nicking ideas from it, is a better description for this post.&lt;/p&gt;
&lt;p&gt;The indieweb is great, but lost interest and tinkering with the site itself eventually.
No doubt a reaction I had maintaining my old NextJS blog, which had deprecated dependencies, two seconds after bootstrapping.&lt;/p&gt;
&lt;h2 id="whats-new"&gt;What&amp;rsquo;s new&lt;/h2&gt;
&lt;p&gt;I was able to get most of these done in a small time, using LLM tools, to give some transparency check my &lt;a href="https://ukr.lk/ai"&gt;/ai&lt;/a&gt; page to learn how these tools are used.
In short not for content text, photos, etc.&lt;/p&gt;
&lt;h3 id="theme-and-update-home-page"&gt;Theme and update home page&lt;/h3&gt;
&lt;p&gt;New theme based on &lt;a href="https://newcss.net/"&gt;newcss&lt;/a&gt; which I have supplemented with custom css.
Goodbye &lt;a href="simplecss.org"&gt;simplecss.org&lt;/a&gt; what a great lesson in semantic HTML.
Home page is no longer just a paginated post list, but shows a sampling of new posts, projects and photos.&lt;/p&gt;
&lt;h3 id="photos"&gt;Photos&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve always had problems in publishing photos, unsure of quality and standards to hold. Therefore I&amp;rsquo;ve made the careful distinction &amp;ldquo;photos&amp;rdquo; not &amp;ldquo;photography&amp;rdquo;,
what ever that means. Goal being to have a chronological timeline of &lt;a href="https://ukr.lk/photos"&gt;/photos&lt;/a&gt; organized in albums of what stopped me in the busy world.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;For the content timestamp purists, please forgive me for inserting postings historically.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="comments"&gt;Comments&lt;/h3&gt;
&lt;p&gt;I had let go of interactivity for some time, as integrating with external platforms is not something that was of interest to me.
But I&amp;rsquo;m easy to please, if you say something is built with &lt;a href="go.dev"&gt;Go&lt;/a&gt; and uses &lt;a href="https://sqlite.org/index.html"&gt;SQLite&lt;/a&gt;, you got my attention.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://remark42.com/"&gt;Remark42&lt;/a&gt; comments engine is hosted on my server and now folks can leave comments.
Also with it comes a &lt;a href="https://ukr.lk/guestbook"&gt;/guestbook&lt;/a&gt; (empty page with a comments box).&lt;/p&gt;
&lt;h3 id="series-taxonomy"&gt;Series taxonomy&lt;/h3&gt;
&lt;p&gt;Posts can belong into a series, this will give a brief intro about the series page and a dedicated page for posts under this series.&lt;/p&gt;
&lt;h3 id="miscellaneous-new-pages"&gt;Miscellaneous new pages&lt;/h3&gt;
&lt;p&gt;The following new pages were added.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ukr.lk/slashpages"&gt;/slashpages&lt;/a&gt; index of top level links.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ukr.lk/resume"&gt;/resume&lt;/a&gt; hypertext copy of my resume.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ukr.lk/colophon"&gt;/colophon&lt;/a&gt; how is this site built.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ukr.lk/ai"&gt;/ai&lt;/a&gt; how LLM tools are used in relation to this site.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="what-to-expect"&gt;What to expect&lt;/h2&gt;
&lt;p&gt;Once again I have supplemented my lack of content with more eye candy. I&amp;rsquo;m going to get into groove of writing more, perhaps bring back &lt;a href="https://ukr.lk/tags/100wd/"&gt;100 words a day&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;More &lt;a href="https://ukr.lk/photos"&gt;/photos&lt;/a&gt;, really pleased with this. Curating and picking highlights and writing some words on them is fun!&lt;/p&gt;
&lt;p&gt;The site typography and styling is really rough, will be refining it more. Maybe a Git based CMS?&lt;/p&gt;</description></item><item><title>Migrating my blog, again (Hugo)</title><link>https://ukr.lk/posts/hugo-blog-migration/</link><pubDate>Sun, 28 Apr 2024 16:19:34 +0530</pubDate><guid>https://ukr.lk/posts/hugo-blog-migration/</guid><media:thumbnail url="https://ukr.lk/posts/hugo-blog-migration/thumbnail_hu_3b8ac3940f048ea9.webp" width="1200" height="900"/><description>&lt;p&gt;Time goes by fast, the last time I posted on this site was in 2022. I&amp;rsquo;m alive and doing well, more than well to be honest, a lot of good news&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;But today let&amp;rsquo;s talk about the state of this website. In the last week there has been a considerable change to the makeup and hosting of this website. It wen&amp;rsquo;t from being a Next.js website hosted on Netlify to being a Hugo SSG(static site generator) on a Debian VPS on Linode. This site has always been an SSG, even with Next.JS it was using the static html export feature.&lt;/p&gt;
&lt;p&gt;

&lt;figure id="image-1" class="image-figure"&gt;
	
		
		&lt;img src="https://ukr.lk/posts/hugo-blog-migration/thumbnail_hu_e6f143ef209fd87a.webp" width="1600" height="1199" class="summary-image" alt="Negambo, Sri Lanka, 2024"&gt;
	
 &lt;figcaption&gt;Image 1: Negambo, Sri Lanka, 2024&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="why-am-i-doing-this"&gt;Why am I doing this?&lt;/h2&gt;
&lt;p&gt;Before getting into specifics, looking back there has been a lot of changes in the way I approach these problems. I must accept my naiveté and short sighted when setting my website four years back.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m looking for simplicity and having control of my website in this new implementation.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I&amp;rsquo;m tired of keeping the dependencies up to date of a JavaScript project&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;The website was one of my first Next.JS projects therefore it has some questionable code and questionable DX.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="migrating-to-hugo"&gt;Migrating to Hugo&lt;/h2&gt;
&lt;p&gt;Hugo is a static site generator written in Go, I&amp;rsquo;ve never been interested in learning Go have always been aware of all the tools that I used daily that are written and maintained with it. Also a year back I took up a new job which uses Go as the primary backend language, but I digress.&lt;/p&gt;
&lt;p&gt;There is no customisation here, I downloaded a copy of Hugo and chucked in my content and bootstrapped a custom theme using &lt;a href="http://simplecss.org"&gt;simple.css&lt;/a&gt;&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;I was able to hit the ground running fairly quickly by dropping my markdown files with YAML frontmatter.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;RSS Feed for next.js blog&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;description&lt;/span&gt;: &amp;gt;-&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; On creating an RSS feed for this blog, and how it&amp;#39;s not as tedious as you think.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;date&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;2021-06-19T17:12:26.723Z&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;thumbnail&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;cmb_np.jpg&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;category&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;projects&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;web-dev&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;tags&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;nextjs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;type&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;post&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;slug&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;rss_feed_nextjs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Configuring multiple taxonomies based on the attributes was straightforward.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[&lt;span style="color:#a6e22e"&gt;taxonomies&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;category&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#39;category&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;tag&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#39;tags&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But one of my biggest pain points was asset management, before there was a singular folder which had all of my images and it was a mess. I wanted to switch over to use &lt;a href="https://gohugo.io/content-management/page-resources/"&gt;page resources&lt;/a&gt; instead, which will have all the assets needed on the content folder itself.&lt;/p&gt;
&lt;p&gt;With my laziness, coaxing chat-gpt and spending more time bug fixing resulted in this script, which migrated all my blog posts to their own folders with relative links to images.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; os
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; shutil
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; re
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;migrate_markdown&lt;/span&gt;(source_dir, destination_dir, base_img_path):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Ensure destination directory exists&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exists(destination_dir):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;makedirs(destination_dir)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Iterate through Markdown files in source directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; filename &lt;span style="color:#f92672"&gt;in&lt;/span&gt; os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;listdir(source_dir):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; filename&lt;span style="color:#f92672"&gt;.&lt;/span&gt;endswith(&lt;span style="color:#e6db74"&gt;&amp;#34;.md&amp;#34;&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Read Markdown file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; open(os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;join(source_dir, filename), &lt;span style="color:#e6db74"&gt;&amp;#34;r&amp;#34;&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; file:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; markdown_content &lt;span style="color:#f92672"&gt;=&lt;/span&gt; file&lt;span style="color:#f92672"&gt;.&lt;/span&gt;read()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Extract folder name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; folder_name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;splitext(filename)[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Create folder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; new_folder_path &lt;span style="color:#f92672"&gt;=&lt;/span&gt; os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;join(destination_dir, folder_name)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;makedirs(new_folder_path)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Move Markdown file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; new_markdown_path &lt;span style="color:#f92672"&gt;=&lt;/span&gt; os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;join(new_folder_path, &lt;span style="color:#e6db74"&gt;&amp;#34;index.md&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; shutil&lt;span style="color:#f92672"&gt;.&lt;/span&gt;copy(os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;join(source_dir, filename), new_markdown_path)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Copy images to folder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; img_paths &lt;span style="color:#f92672"&gt;=&lt;/span&gt; re&lt;span style="color:#f92672"&gt;.&lt;/span&gt;findall(&lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/img/([\w-]+.\w{1,5})&amp;#34;&lt;/span&gt;, markdown_content)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; img_path &lt;span style="color:#f92672"&gt;in&lt;/span&gt; img_paths:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; img_filename &lt;span style="color:#f92672"&gt;=&lt;/span&gt; os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;basename(img_path)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; shutil&lt;span style="color:#f92672"&gt;.&lt;/span&gt;copy(os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;join(base_img_path, img_path), os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;join(new_folder_path, img_filename))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Update image paths to be relative&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; markdown_content &lt;span style="color:#f92672"&gt;=&lt;/span&gt; re&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sub(&lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/img/([^&amp;#39;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;\(\)]+)&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;\1&amp;#34;&lt;/span&gt;, markdown_content)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Write updated Markdown content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; open(new_markdown_path, &lt;span style="color:#e6db74"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; new_file:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; new_file&lt;span style="color:#f92672"&gt;.&lt;/span&gt;write(markdown_content)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Example usage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source_dir &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;./posts&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;destination_dir &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;./content/posts&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;base_img_path &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;./static/img&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;# Base path for images&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;migrate_markdown(source_dir, destination_dir, base_img_path)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="tips-i-wish-id-knew-days-back"&gt;Tips I wish I&amp;rsquo;d knew days back&lt;/h2&gt;
&lt;p&gt;Yes to RTFM, but these are the customisations that were done.&lt;/p&gt;
&lt;h3 id="customize-markdown-image-rendering"&gt;Customize markdown image rendering&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s best that the image tags in markdown be rendered in a &lt;code&gt;figure&lt;/code&gt; tag and have compression applied you can do that using an hook in the layouts directory. &lt;code&gt;layouts/_default/_markup/render-image.html&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{- $imgURL := .Destination -}}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{- $altText := .Text -}}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ $image := .Page.Resources.Get $imgURL }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;figure&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	{{ if $image }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		{{ $image = $image.Process &amp;#34;resize 1000x webp q50&amp;#34; }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;		&amp;lt;&lt;span style="color:#f92672"&gt;img&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $image.RelPermalink }}&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;class&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;summary-image&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	{{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;figcaption&lt;/span&gt;&amp;gt;{{ $altText }}&amp;lt;/&lt;span style="color:#f92672"&gt;figcaption&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;figure&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This also has image processing, where I requested that the images be resized to 1000px on width and exported as &lt;code&gt;webp&lt;/code&gt; with 50% quality.&lt;/p&gt;
&lt;h3 id="minifying-css"&gt;Minifying CSS&lt;/h3&gt;
&lt;p&gt;I found the documentation on this, but what I missed was the fact that the css files should be in the &lt;code&gt;assets&lt;/code&gt; directory not the &lt;code&gt;static&lt;/code&gt; directory.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ $style := resources.Get &amp;#34;style.css&amp;#34; | minify | fingerprint }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{{ $custom := resources.Get &amp;#34;custom.css&amp;#34; | minify | fingerprint }}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $style.Permalink }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;{{ $custom.Permalink }}&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="minifying-html-content"&gt;Minifying HTML content&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;d guessed this is done via configuration, but it&amp;rsquo;s done using during the build stage using a cli flag&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hugo --minify
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Migrating to hugo only took me a couple of days, and compared to the custom Next.js code base, this is much better DX and updating my toolchain is only a single step to replace the hugo binary. This is one of the reasons not choosing to opt into using Tailwind as well.&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Shall post about that soon&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Did use dependbot, but then proceeded to forget about it&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Do enjoyed my old website theme made with Tailwind, but wanted to get started quickly. Might re-visit it later&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>RSS Feed for next.js blog</title><link>https://ukr.lk/posts/rss_feed_nextjs/</link><pubDate>Sat, 19 Jun 2021 17:12:26 +0000</pubDate><guid>https://ukr.lk/posts/rss_feed_nextjs/</guid><media:thumbnail url="https://ukr.lk/posts/rss_feed_nextjs/cmb_np_hu_e80f3226e8e4b1e9.webp" width="1200" height="810"/><description>&lt;p&gt;This blog finally has an RSS feed, I welcome you to 1999. When building my own blog instead of using a blogging platform I knew I was getting into a world of pain.&lt;/p&gt;
&lt;p&gt;Most of the site is complete and usable, but what lacked was an RSS feed for potential followers to subscribe with! Let&amp;rsquo;s leave the talk and get-into it!&lt;/p&gt;
&lt;p&gt;

&lt;figure id="image-2" class="image-figure"&gt;
	
		
		&lt;img src="https://ukr.lk/posts/rss_feed_nextjs/cmb_np_hu_e41ebf8667096c36.webp" width="1600" height="1080" class="summary-image" alt="Colombo, Sri Lanka 2017, Newspaper Stand"&gt;
	
 &lt;figcaption&gt;Image 2: Colombo, Sri Lanka 2017, Newspaper Stand&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="npm-dependencies"&gt;NPM Dependencies&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ll have to install a new package aptly named &lt;a href="https://www.npmjs.com/package/rss"&gt;rss&lt;/a&gt; for making it easy to generate the RSS feed. Why reinvent the wheel, eh?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yarn add rss @types/rss
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;note: I added &lt;code&gt;@types/rss&lt;/code&gt; as my next.js project is in typescript&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="making-a-fake-route"&gt;Making A Fake Route&lt;/h2&gt;
&lt;p&gt;This is probably the point some might have scratched their heads. How can we create a custom dynamic file during build time?&lt;/p&gt;
&lt;p&gt;There is no easy way, but this hack works perfectly. &lt;strong&gt;Create a new file in pages&lt;/strong&gt; named something like &lt;code&gt;static_file_build.tsx&lt;/code&gt; (Easter Egg!)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What we will make this route do is,&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Render Dummy Page.&lt;/li&gt;
&lt;li&gt;Load Latest Post Details.&lt;/li&gt;
&lt;li&gt;Write a XML string to a file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;This file serves no display purpose but to ber an entry point to build our rss feed.&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-ts" data-lang="ts"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DummyPage&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; () &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Dummy Page&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;buildRss&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;posts&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;PostEntity&lt;/span&gt;[])&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// TODO;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getStaticProps&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; () &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Depends On Your Implementation
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;posts&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;PostAPI&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getLatest&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Generate Feed XML
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;feedXml&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;buildRss&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;posts&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Write Generated RSS Feed To Public Folder
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;writeFileSync&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;public/rss.xml&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;feedXml&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;props&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;posts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DummyPage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As shown above, it&amp;rsquo;s clear how this works. Depending on your backend get your latests posts loaded and let&amp;rsquo;s get cracking on building the feed!&lt;/p&gt;
&lt;h2 id="building-the-feed"&gt;Building The Feed&lt;/h2&gt;
&lt;p&gt;Now this is where the installed &lt;code&gt;rss&lt;/code&gt; package comes to the rescue. It has an easy interface/api to build the feed and export the xml. Let&amp;rsquo;s complete the buildRss function!&lt;/p&gt;
&lt;h3 id="create-feed-object"&gt;Create Feed Object&lt;/h3&gt;
&lt;p&gt;The first task is to create the feed object. It should be instantiated with your basic site details.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-ts" data-lang="ts"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;feed&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;RSS&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Kaveen R&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;description&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;blog posts&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;feed_url&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;BASE_URL&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/rss.xml`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;site_url&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;BASE_URL&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;pubDate&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="add-posts-to-feed-object"&gt;Add Posts To Feed Object&lt;/h3&gt;
&lt;p&gt;Next task is to iterate through all your blog posts and add them to the aforementioned feed object.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-ts" data-lang="ts"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Add Each Post to feed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;posts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;)&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Take Markdown Content &amp;amp; Convert To basic HTML
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ReactDOMServer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;renderToStaticMarkup&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;ReactMarkdown&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;escapeHtml&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;source&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;feed&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;post.matter.title&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;description&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;body&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;BASE_URL&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/posts/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;matter&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;slug&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;date&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;post.matter.date&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;category&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;post.matter.categories&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;author&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Kaveen R&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Important Notes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;description&lt;/code&gt;&lt;/strong&gt; should contain an HTML representation of your blog post content. Buy invoking &lt;code&gt;ReactDOMServer.renderToStaticMarkup()&lt;/code&gt; we&amp;rsquo;re generating HTML for a given React component. &lt;strong&gt;This will change with the libraries you use&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;categories&lt;/code&gt;&lt;/strong&gt; is a list of unique strings, when using customizable RSS readers users can filter your latests post using the mentioned catagories.&lt;/p&gt;
&lt;h3 id="serializing-the-feed"&gt;Serializing The Feed&lt;/h3&gt;
&lt;p&gt;Last step is to convert the feed object into an XML string which will be written to file by our dummy page!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-tsx" data-lang="tsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;feed&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;xml&lt;/span&gt;({&lt;span style="color:#a6e22e"&gt;indent&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now when building your page you&amp;rsquo;ll see that feed is generated an place on &lt;code&gt;/public/rss.xml&lt;/code&gt;!&lt;/p&gt;
&lt;h2 id="housekeeping"&gt;Housekeeping&lt;/h2&gt;
&lt;p&gt;There are a couple of more things to do! We ant to make sure that our RSS feed is complaint and also can be found by feed readers. This is how to quickly do that&lt;/p&gt;
&lt;h3 id="checking-for-feed-errors"&gt;Checking For Feed Errors&lt;/h3&gt;
&lt;p&gt;To Make Sure we deliver the best RSS feed to all users, we can validate it using a tool such as &lt;a href="https://validator.w3.org/feed/"&gt;W3 Validator&lt;/a&gt; which will validate and give suggestions on how to make the feed better.&lt;/p&gt;
&lt;h3 id="making-sure-the-feed-is-discoverable"&gt;Making Sure The Feed Is Discoverable&lt;/h3&gt;
&lt;p&gt;On one of your main next.js template(such as &lt;code&gt;_app.ts&lt;/code&gt;) include the following in the header, this meta tag will guide compatible software to the feed.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;Head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;alternate&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;application/rss+xml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;RSS&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/rss.xml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;Head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="adding-rssxml-to-gitignore"&gt;Adding &lt;code&gt;rss.xml&lt;/code&gt; to gitignore&lt;/h2&gt;
&lt;p&gt;This is to anyone who is using GIT VSC. To avoid commiting the RSS file to VCS accidentally add the feed reference to the &lt;code&gt;.gitignore&lt;/code&gt; file.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public/rss.xml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That&amp;rsquo;s it folks! Now you got a RSS Feed for your blog. It maybe 22 years too late, but at-least we got it!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="complete-code-sample"&gt;Complete Code Sample&lt;/h2&gt;
&lt;p&gt;Here is the complete code sample which we ran through today!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-tsx" data-lang="tsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;RSS&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;rss&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ReactDOMServer&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;react-dom/server&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ReactMarkdown&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;react-markdown&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;DummyPage&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; () &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Dummy Page&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;buildRss&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;posts&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;PostEntity&lt;/span&gt;[])&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Create Feed With Site Details
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;feed&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;RSS&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Kaveen R&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;description&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;blog posts&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;feed_url&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;BASE_URL&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/rss.xml`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;site_url&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;BASE_URL&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;pubDate&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Date()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Add Each Post to feed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;posts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;)&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Take Markdown Content &amp;amp; Convert To basic HTML
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ReactDOMServer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;renderToStaticMarkup&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;ReactMarkdown&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;escapeHtml&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;source&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;feed&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;({
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;post.matter.title&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;description&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;body&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;BASE_URL&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/posts/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;matter&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;slug&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;date&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;post.matter.date&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;category&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;post.matter.categories&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;author&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Kaveen R&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Serialize Feed &amp;amp; Return as string
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;feed&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;xml&lt;/span&gt;({&lt;span style="color:#a6e22e"&gt;indent&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getStaticProps&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;async&lt;/span&gt; () &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Depends On Your Implementation
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;posts&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;PostAPI&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getLatest&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Generate Feed XML
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;feedXml&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;buildRss&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;posts&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Write Generated RSS Feed To Public Folder
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;writeFileSync&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;public/rss.xml&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;feedXml&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;props&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;posts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>All Hail The JAM Stack!</title><link>https://ukr.lk/posts/all-hail-the-jam-stack/</link><pubDate>Mon, 08 Jun 2020 14:33:40 +0000</pubDate><guid>https://ukr.lk/posts/all-hail-the-jam-stack/</guid><media:thumbnail url="https://ukr.lk/posts/all-hail-the-jam-stack/site_june_2020_c_hu_b397bef19befb53e.webp" width="1200" height="1015"/><description>&lt;p&gt;I was having troubles with my website. I got it settled up just to be a landing page. A website with a high bounce rate and low retention yikes!&lt;/p&gt;
&lt;p&gt;With leaving social media, I needed a new home to settle down my thoughts and have all my creations in one place instead of relying on other sites. Time to make the web personal again!


&lt;figure id="image-1" class="image-figure"&gt;
	
		
		&lt;img src="https://ukr.lk/posts/all-hail-the-jam-stack/site_june_2020_c_hu_aa07bd95ba8bbefb.webp" width="1600" height="1354" class="summary-image" alt="What it looks like - June 2020"&gt;
	
 &lt;figcaption&gt;Image 1: What it looks like - June 2020&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="whats-a-stack"&gt;What&amp;rsquo;s a stack?&lt;/h2&gt;
&lt;p&gt;A stack is simply the selection of software that you use to run an application. My first website ran on &lt;strong&gt;LAMP&lt;/strong&gt; Which was &lt;em&gt;Linux, Apache, Mysql and PHP&lt;/em&gt;. It wasn&amp;rsquo;t cool to have a /static website those days.&lt;/p&gt;
&lt;h2 id="then-whats-with-the-jam"&gt;Then What&amp;rsquo;s with the JAM?&lt;/h2&gt;
&lt;p&gt;Gone are the days of bulky server bootstrapping to get a simple website off the ground. JAM stack made it simple, it stands for,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;J&lt;/strong&gt;avascript.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A&lt;/strong&gt;PIs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M&lt;/strong&gt;arkup.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The JAM stack is not really about the technologies used as some even totally drop the J from the stack. But it&amp;rsquo;s a way to approach building websites.&lt;/p&gt;
&lt;p&gt;Instead of having bulky databases and web-servers, sites are to be pre-rendered using the APIs and Markup.&lt;/p&gt;
&lt;center&gt;
 &lt;b&gt;I'm not going to regurgitate on the JAM Stack,&lt;br/&gt;read more on &lt;a href="https://jamstack.org/"&gt;jamstack.org&lt;/a&gt;&lt;/b&gt;
&lt;/center&gt;
&lt;h2 id="so-whats-my-jam-stack--why"&gt;So what&amp;rsquo;s my JAM Stack &amp;amp; Why?&lt;/h2&gt;
&lt;p&gt;My old website ran on &lt;a href="https://gohugo.io/"&gt;Hugo&lt;/a&gt; which was technically JAM, but I never filled it with content as I was just lazy to read the docs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Javscript:&lt;/strong&gt; This time I opted to use &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt; and wrote my own CMS and rendered the UI with the &lt;a href="https://bulma.io/"&gt;Bulma&lt;/a&gt; CSS framework.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;APIs:&lt;/strong&gt; As said before I use my own custom one file Typescript CMS that reads off files. I call my &lt;em&gt;API&lt;/em&gt; the &lt;em&gt;&lt;strong&gt;_grail&lt;/strong&gt;&lt;/em&gt; which has all the data to generate this blog.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;_grail
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── categories
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── fintech.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── life.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── projects.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── web-dev.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── microblog
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── 2020-06-07T14:50:49+0000.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── 2020-06-07T15:21:14+00:00.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├── pages
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── page_about.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ├── page_contact.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ └── page_home.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;└── posts
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── 2019-06-08_All-Hail-The-JAM-Stack.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── 2020-05-08_Putting-the-past-on-disk-a077e62019eb.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt; directories, &lt;span style="color:#ae81ff"&gt;24&lt;/span&gt; files
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Markup:&lt;/strong&gt; Good old markup with frontmatter to annotate metadata for each of the markdown posts&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;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;"&gt;&lt;code class="language-md" data-lang="md"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;slug: &amp;#34;1591541449&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;date: &amp;#34;2020-06-07T14:50:49+0000&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Hello World! It&amp;#39;s my lonely &lt;span style="font-style:italic"&gt;*micro-blog*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="current-workflow"&gt;Current Workflow&lt;/h2&gt;
&lt;p&gt;Current workflow requires me to write markdown on my text-editor and push it to a private github repository and afterwards it&amp;rsquo;s deployed instantly(Thanks to &lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt;), &lt;strong&gt;but there are a couple of pain-points&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Quickly generate Content Templates&lt;/em&gt; - Currently I copy and old post markdown file and edit it, need some CLI.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Static file management&lt;/em&gt; - There is none, I currently just convert the images using IM and dump the images into the /static directories.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s not the best, I have to do my own styling and content structure. This allows me total control over the site and be able to expand it, which I will certainly do. Thanks for hanging on folks.&lt;/p&gt;</description></item></channel></rss>