Rebuilding my Personal Website in 2021

Background

Background

I first launched my website in 2018 and used this free Bootstrap CV theme to quickly set up my profile before I applied for jobs after completing university. I was content after publishing my first iteration but over time grew tired of the design and longed for adding other cool features like a blog, newsletter, and a custom backend CMS. Once I got a full-time job I found the task too difficult and time-consuming to do. I didn’t want to get a WordPress theme and get it up and running quickly. I wanted to build it from scratch while using a Modern tech stack to learn to improve my front-end development knowledge. It was time for change and I started building it in January 2021.

Inspiration

I got the inspiration for my site after looking at Brian Lovin’s 2020 personal site that is currently open-source. You can check it out here. Here is a snapshot of how it looks.

New Stack

My new site is currently built using Next.JS and TailwindCSS for the Frontend. I loved the developer experience of styling web interfaces using Tailwind and the Next.JS being the best React framework to build Server-side rendered apps together with Vercel that provides a neat platform to host your apps and makes CI/CD, Deployment easier for developers. I recommend checking out these frameworks if you are interested in React and CSS.

The Backend is built using Strapi, a really good Headless CMS. Some many Headless CMS is currently available and I spent quite a lot of time/energy testing them all. However, I ended up choosing Strapi since it had a neat interface, was open-source so I could host it on my server and the backend was built in React so adding custom plugins to the interface was easy and Strapi provided good documentation on how to integrate them.

Using Next.JS

I currently love Next.JS as my go-to Javascript framework for building fast React web applications. Thanks to it having Automatic Static Optimization you can build both statically generated and server-rendered pages. I built the site with a decent local environment setup using Prettier, ESLint for linting while writing with Typescript helped in type checking.

Hosting on Vercel

Vercel is a cloud platform that allows developers to host websites and web services that deploy instantly, and require no supervision and configuration. Some of the main pros include fast refresh, flexible data caching, and easy integration with your repositories at Github, Gitlab, and Bitbucket. It was cool that Vercel was the company that built the Next.JS framework so they were a first choice for the same. Luckily it has a flexible free plan for hosting static websites and single-page applications. I was able to deploy my website to Vercel and set up my domain to the site.

Using TailwindCSS

I’ve been a huge fan of Tailwind ever since it came out in 2019. By default, it makes the developer think in components as you can easily separate a site’s elements that reduce the cognitive load during styling and is faster than writing CSS or CSS-in-JS. I especially like the inclusion of styling a Dark Theme of which you can enable by default or use the system default setting. Using next-themes provided an easier abstraction to achieve Dark Mode without flashing while changing themes.

SEO

Every blog post is automatically populated with meta tags using next-SEO. This includes title, description, meta tags, twitter metadata.

RSS Feed Generation

An RSS feed is auto-generated from your blog post feed. I use RSS to keep up with a few tech blogs, webcomics and use 1Feed to sync all the apps I have. So I thought it was a good idea to build one for my site. This is generated manually after fetching all the posts like below.

// Generate One Item
const generateRssItem = (post: Post): string => `
<item>
<guid>https://davidamunga.com/blog/${post.slug}</guid>
<title>${post.title}</title>
<link>https://davidamunga.com/blog/${post.slug}</link>
<description>${post.excerpt}</description>
<pubDate>${new Date(post.published_at).toUTCString()}</pubDate>
</item>
`
//Generate Entire Feed
export const generateRss = (posts: Post[]): string => `
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Blog - David Amunga</title>
<link>https://davidamunga.com/blog</link>
<description>Thoughts about Development,Design and Products</description>
<language>en</language>
<lastBuildDate>${new Date(posts[0].updated_at).toUTCString()}</lastBuildDate>
<atom:link href="https://davidamunga.com/rss.xml" rel="self" type="application/rss+xml"/>
${posts.map(generateRssItem).join('')}
</channel>
</rss>`

The RSS feed is generated at build time using the getStaticProps function and is saved using the fs module to a root rss.xml file in the public folder. It also fetched again after 6 hours.

// Generate RSS
export const getStaticProps: GetStaticProps = async () => {
const postResponse = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}blogs`)
const posts = postResponse.data
const rss = generateRss(posts)

fs.writeFileSync('./public/rss.xml', rss)

return { props: { posts }, revalidate: 6 * 60 * 60 }
}

Future Plans

As I’m happy with how the new design turned out. I hope to make some future additions. I intend to make a richer content view for the blog posts incorporating more embeds from different Media. It would also be great to have some neat micro-interactions/transition animations while sticking to its plain theme. Furthermore, I wish to have it working with Apollo GraphQL with Caching to boost performance on the site.

Originally published in https://davidamunga.com

Software | Design | Products | Hiking