jasonloong.com v2 section image

jasonloong.com v2

Rewritten

Since jasonloong.com v1.1, the website has been rewritten from scratch! (well, mostly)

I was satisfied with v1.1, but there were still workarounds that led to bigger issues when the site was in production.

Photo - L1003115.jpg
L1003115.jpg
EXIF

The development process was not fully best-practised as well, with many untyped/any API responses from Directus, slap-on get-it-working-first code, which months later turned into a nightmare to debug when certain quirks happened on my site. 🙈

After getting v1 up, there were many mini projects in between that I’ve written since, which strengthened my experience developing with Nuxt overall.

v1.1 Not fully SSR compatible

As my markdown content uses custom Vue components, it was difficult trying to get a complete SSR-rendered website while using MarkdownIt as my main parser/renderer.

The result, as described in the v1.1 post, was a workaround which rendered a custom HTML component and then rehydrated after the page had been loaded.

While SEO is not critical to this website, the implementation was half-baked.

Nuxt MDC

Everything worked with the Nuxt/MDC renderer (it should, as Nuxt/Content also uses it), but entry.js's bundle size after building was a no-go. It is just too large for a normal non-interactive website for on-demand/runtime dynamic CMS content.

From my previous experience with MarkdownIt, with such a large bundle size, pretty much means at some point, the Markdown content will be client rendered. Even if it doesn't, having users load 500kb of JS files is not ideal, let alone more bandwidth for my photo-heavy website.

Photo - L1003364.jpg
L1003364.jpg
EXIF

A dead-end till one comment made its way to one of the repo issues: With Nuxt Used It adds 30 thousand lines of code. #377

Ah, yes, let's try that. Bundle size issue gone. Reactive variables work. Async pulling additional data for my photos works as well.

Looking back, while the comment "made sense" to the experienced Nuxt users, it didn't occur to me at the time because I started with Vue development (SPA) and then transitioned to the Nuxt framework, mainly for the improved developer experience. SSR was an afterthought and eventually led to using/testing it as my website.

So the idea of having the "server route" do all the work, instead of just "pulling data", and trust that the hydration magic happens is not a mindset that I have while developing in Nuxt. My brain was wired to think in Vue's SFC style, so most logic should be in the component's markdownRenderer.vue.

A renewed understanding, appreciation ❤️ of the flexibility, powers of server routes, Nitro and Nuxt.

The site now utilises Nuxt's MDC library to render dynamically pulled CMS Markdown content entirely server-side and hydrate it accordingly if the user navigates on the website.

UI/Layout

Photo - L1004205.jpg
L1004205.jpg
EXIF

Migrated to use Nuxt UI, from DaisyUI

From Pinia to useState

Pinia, the go-to store for most users, I presume. Somehow, it didn’t work for me as expected during this rework. Some components refuse to get the state and are forced to go into client-side hydration, which breaks my layout. Might be the reason why things do not work out as expected most of the time, especially hydration mismatches.

Decided to use Nuxt’s provided useState, which works as expected when Nuxt is in SSR mode.

If you are like me, having those few “go to” libraries on new projects like “Pinia” store to install, try using useState if your SSR site is having issues hydrating.

CI/CD, Docker

Other than site development, I also implemented a CI/CD flow in my self-hosted GitLab instance, which helps to push the latest main branch/image to my host.

v1.1 was built on my development machine, rsync the new JS files over to my host, with a final SSH into the host to restart PM2 manager. I tried building Nuxt on my fairly limited DigitalOcean droplet instance, but it would fail due to memory issues.

Now, my new CI/CD builds the website on one of my higher-spec virtual machines, sends it over to a self-hosted Harbour Docker image repository, and with the final deployment pipeline, pulls the latest image of the website. Discord notifications are set up so that I know it's ready to be visited and ensure everything works.

v2

Photo - Cleaning - color
Cleaning - color
EXIF

The layout is now as initially imagined, and not compromised due to previous workaround issues.

While there's still some metadata that is not being handled/generated, as long as it is not an issue that will affect the site's intended rendering, SEO-related improvements can be dealt with later.

Hopefully, this will be the last time within the next few years before the site requires a significant rewrite.

Title:

jasonloong.com v2

Excerpt:

Rewritten website

Posted On:

2025 Sep 15 (about 8 hours ago)

Updated On:

2025 Sep 15 (about 3 hours ago)

Topic Views: 1