Personal Portfolio

Written August 21, 2022 • Last edited August 21, 2022


Intro

This is going to be a shorter post since this website speaks for itself, but I do want to share some general information and resources for those wanting to create something similar. I also want to highlight some details that I learned were customizable while building my site.

Tools / technologies used

I started this project with a helpful tutorial from Ben Awad. The site utilizes Next.js's static site generation (SSG) feature, which allows it to fetch posts from a content management system (CMS) and dynamically render HTML elements for each from just a markdown (.md) file. It's confusing, and I can't really explain how anything works, but Next.js basically makes things a lot easier and cleaner. I used to try creating websites with pure HTML and CSS, and I hated every bit of it, but I actually genuinely enjoyed putting this site together with Next.js once I got the ball rolling.

I'm also not a fan of CSS, but I did find Tailwind CSS to be a very nice framework that made styling things feel much better. Tailwind is an example of "atomic" or "functional" CSS, a different approach to styling which favors applying many single-purpose classes with names based on visual function. There are a few of these out there, but I chose Tailwind because it has great out-of-the-box markdown styling and still allowed for as much customization as I wanted using the configuration file and by overwriting the generated default styles in output.css from input.css:

npx tailwindcss -i ./styles/input.css -o ./styles/output.css --watch

See the installation guide for more information about how it works. Tailwind also provides great documentation with the ability to "quick search" for a page regarding the certain thing you're trying to do.

To learn more about atomic CSS in general, I highly recommend reading this post by Anthony Fu—it's where I learned about it in the first place!

For my markdown parsing and codeblock syntax highlighting, I used Node.js's npm (Node package manager) to install gray-matter for markdown-to-object conversion (splits content and metadata), marked.js for markdown-to-HTML parsing, and highlight.js for syntax highlighting. The first two are also included in Ben Awad's tutorial linked above.

Finally, another great thing about Next.js is that the creator, Vercel, makes it easy to deploy. They'll host your site for free, and you can buy a custom domain name (from somewhere like namecheap.com) and assign it. There's also Git repository integration, so your pushed changes can be deployed automatically.

A few details

I love finding little details that can be customized.


When browsing through the Tailwind docs, I saw that I could edit the color of text selection:

input.css
@layer base {
  html {
    @apply selection:bg-[#334155] selection:text-slate-100;
    @apply bg-[#ededed];
  }
  html.dark {
    @apply selection:bg-slate-100 selection:text-slate-800;
    @apply bg-htmldark;
  }
  h6 {
    @apply text-xs ml-2 mt-1.5;
  }
}

This is also where I fixed the background color of the page (when zoomed too far out on mobile) and added a custom styling for h6, which I use specifically for the little file name above my codeblocks sometimes.

While messing with selection color, I noticed that you could select the text in my navbar, which felt wrong when doing "select all" (ctrl+A), which I cared about for some reason. To combat this, I just had to add select-none to my navbar component.


I also put in a lot of effort to support a fully styled light mode, despite its inferiority to dark mode, because I liked the "Projects / Posts" colors. I had to do this weird double-invert thing in order to flip the colors of the background image and text properly:

background-container.js
export default function BackgroundContainer({children}) {
  return (
    <div className='invert dark:invert-0 bg-cover bg-center h-screen'
    style={{backgroundImage: "linear-gradient(rgb(18 18 18 / 0.8), rgb(18 18 18 / 1)), url('/images/background.png')"}}>
      <div className='invert dark:invert-0'>
        {children}
      </div>
    </div>
  );
}

Also in that code snippet, my background color does this nice fade to dark / light as the page goes down since the image won't span the length of the page—similar to how Steam profile backgrounds behave.


Conclusion

Thanks for reading through! I hope you find this collection of information helpful if you start a Next.js SSG project of your own.