Welcome to v3.1
This portfolio has been a long time coming--some would say too long. Version 1 was a static page that had some (very wonky) CSS-only animation--the developer I was then shied away from using JavaScript. With v2, I tried to apply everything I'd learned in developing WordPress sites. However, as I became more comfortable working on that platform, I soon outgrew that version, too. About nine months in the making, version 3.1 of this portfolio site feels like a breath of fresh air.
Insights
When I conceptualized version 3, I set out to learn something new. I wanted to try React or Next.js but both felt like overkill for something as simple as a personal site. I decided why not try going headless? I figured something like Statamic would be nice since I love working with Laravel.
Statamic is very opinionated, though, and the more I built out the backend, the more I realized this was not the right platform.
I design...sometimes
I'm not a designer. No really, I'm not a designer. For this build, inspiration just happened to come from my favorite VS Code theme. And I have to admit that even that design went through multiple iterations. And I still hadn't found the right replacement for Statamic.
I went through framework after framework both for the front and the back: Strapi, Gatsby, Next.js. After a few months, a friend had to intervene.
I think I can. I know I can...
"It's never going to be as good as it is in your head. The point is that it's good enough and that you're the one to build it."
With my friend's words in mind, I sucked up my pride and got to work. I swapped out Statamic for Sanity, which allows me more flexibility to define fields than its predecessor, and there's the added bonus of a mighty asset CDN and smart image manipulations.
Next up was ditching Next because it's the equivalent of a sledgehammer for my purposes. I really just needed a sturdy framework for SSR that I could deploy on DigitalOcean. I landed on Nuxt, which was beginner-friendly enough for me to start building with right away.
An experience
There were various points in this build when I found myself dealing with unfamiliar concepts. One such point was while building the color scheme toggle for the site. Originally it was going to be a simple toggle, but then I realized it's better UX when the user is given the option to set the theme to follow the system's preference. Since the portfolio is in "dark" mode by default, the theme is only ever toggled by adding a "light" class modifier to the body.
.light-mode {
--c-foreground: #403f53;
--c-background: #fbfbfb;
--c-action: #994cc3;
--c-selection: #90a7b2;
--c-success: #0c969b;
--c-accent-1: #bc5454;
--c-accent-2: #4876d6;
--c-accent-3: #93a1a1;
--c-accent-4: #d6d6d6;
--c-menu-bg: #e0e0e0;
--c-header-bg: rgb(251, 251, 251, .7);
}
To handle system preferences, I added a listener for the color mode reactive reference. This listener toggles the 'light-mode' class on the body element.
const changeColorMode = (newMode:string) => {
const currentMode = document.querySelector('body')?.classList.contains('light-mode') ? 'light' : 'dark';
if ( newMode !== 'system' && currentMode === newMode ) {
return;
}
if ( 'system' === newMode ) {
const systemMode = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
document.querySelector('body')?.classList.toggle('light-mode', systemMode === 'light');
} else {
document.querySelector('body')?.classList.toggle('light-mode', newMode === 'light');
}
colorMode.value = newMode;
localStorage.setItem('color-mode', newMode);
};
Now that the global state wasn't a simple binary on/off, I had to make use of Nuxt's advanced state management using composables. This was a newer concept that built on my knowledge of reactive state and how that's shared across components.
Summary
I had a lot of fun while building this site and I feel that I learned a lot while doing so. This inspired me to create a "blog" section on the site where I could document lessons learned. If nothing else, these will serve me to track my own growth.