How it all started
Back in 2018 I needed to update my portfolio site. I thought I'd steer away from current trends and build a site that tapped into the 80s and 90s Cyberpunk aesthetic.
The first iteration
I was learning React when I first built this website, and while overkill for a personal portfolio site, it was a great opportunity to learn and experiment with learning it. I've found the best way to learn is by actually making something that you intend to use and ship.
The no-brainer choice at the time was Create React App. It served me well in getting things up and running without having to fuss about with config. On top of that, I was using Styled Components, Tween.js, and React Transition Group. I was also playing with some early Three.js effects like the displacement sphere that still resides on the homepage.
Since then I've used this website as a playground for experimenting with new tech and techniques, so over time I've overhauled pretty much everything.
Migrating to Next.js
With Create React App I was using a somewhat janky and unmaintained package to prerender the site as static HTML in Puppeteer. This worked okay for the most part, but I wanted a more robust solution for posting articles (like this one you're reading) using MDX. I had a half baked version of this lying dormant in the repo, but it never felt good enough to publish. I looked at a few options like Gatsby, Vite, and Parcel, and Remix, but Next.js stood out as the most suited to my needs.
- The site is now based on Next.js. Is a much better fit than Create React App. For now I'm just using it to create a static export, but maybe I'll add some server rendered stuff in the future.
- Styling is now vanilla CSS with postcss to add support for the future native CSS nesting and custom media queries features. I'm using CSS modules instead of BEM syntax to avoid style conflicts.
- For generating pages from
.mdx
files, I'm using Kent C Dodds' mdx-bundler. In combination with Next.js it makes generating pages from.mdx
files really quick and simple. - For animation I've moved from Tween.js and React Transition Group to just Framer Motion.
- 3D effects are still all using Three.js, but I've added
three-stdlib
as a better maintained replacement for modules from Three's examples.
Not all smooth sailing
For the most part, the migration was pretty straight-forward. The way I has structured the site with React Router lent itself well to conforming with Next.js's file-based routing, and I was already using postcss for styling. I did, however, encounter a couple of problems:
1. Route transitions
There was a bit of a conflict when it came to animated route transitions. Next.js will immediately yank out all of the styles for the previous page when navigating to a new one. This works great when you're not animating between pages because it cleans up any unused styles form hanging around. When you are animating the page transition though, all of a sudden the previous page becomes jarringly completely unstyled as it transitions out. This problem one of the most commented and reacted to issues on the Next.js repo, so hopefully there's a fix soon, but for now I've dropped in a hack to fix things from the issue's comments.
2. Scroll restoration
Somewhat related to the route transitions, I had to opt out of both Next.js's and the native browser's scroll restoration in order to prevent the browser immediately scrolling to the top when the page started transitioning out. Next.js also doesn't appear to handle shifting focus when linking to the id of an element within the page, so I added that in for accessibility.
Looking back, and forward
I look forward to continuing to use this site as a playground, and it'll be interesting to compare the next iteration to where it is today.