Building and deploying the first version of my portfolio page

Hands on time! After a brief consideration, we get to actually build and ship code to production for the site you're currently looking at.

First of all, we generate the site from a template, using the command:

npx create-next-app@latest jpgc

Using most of the defaults, we end up with:

  • TypeScript: to add strict typing to our code, so it's easier to maintain and understand; since JavaScript has no strict typing built in.
  • React: possibly the most popular framework for web app development right now. It allows us to create reactive components, while leaving the structure and everything else to us.
  • Next.js: Next.js it's a self-proclaimed React framework, as React itself doesn't have . It comes with a lot of goodies, like Server Side Rendering (which enhances initial load times a lot), build setup, convention-based routing, optimizations, and a lot more. Unless you're building on top of an existing app, I recommend using frameworks like Next or Nuxt (the Vue equivalent), since it takes away a lot of the complexity, since you can adopt conventions instead of thinking about them from scratch.
  • Tailwind CSS: it provides a bunch of CSS utilities to add styling to your HTML, through classes that already implement almost everything you need. From flex, to text-formatting, Tailwind has it all. It can be sort of a I suggest setting up your editor, to benefit from auto-complete and automatic code formatting (powered by Prettier).
  • PostCSS: this is a CSS post-processor. This helps you write cleaner CSS without worrying that much about browser support. You should still mind the browser compatibility for your app, but with PostCSS you don't have to do stuff like prefixing your CSS attributes for proper support.
  • ESlint: code lint + plugins. I cannot assert how important and time saving is to have a tool like this one. ESlint is pretty powerful, and it prevent errors like creating a component function that returns nothing. Also, in my opinion, all of your code-styling standards should be tested automatically, or not exist at all; you shouldn't waste time discussing whether or not a semicolon is required in a certain condition on every code review.

This is enough to build a production-grade application right from the beginning, and just from a simple command - and for free!

You gotta love how simple is to get started with a whole set of great tools ✨

Deploying the first version

As mentioned before, we're using Vercel as our infrastructure. It's really a time saver for simple applications, as we can follow a simple setup to allow us to deploy automatically when a commit is pushed to our `main` branch.

Under the hood, Vercel will run whatever is inside our `build` command (as defined in package.json), which is mapped to `next build`. It's useful to know that you run this command locally, to take a look and test the actually deployed version of your app.

Vercel default for deployment is

After you followed the deploy setup instructions, you'll end with something like this deployed to [your-app-name].vercel.app, which is neat, since you can have relatively short links like https://jpgc.vercel.app/, which are useful in case you want to share a preview or maybe a coding interview solution, with a nice little link ✨

Vercel's empty page boilerplate

Building my actual portfolio page

At this point, I've just proven that I can follow simple instructions from the Next's documentation, but the overall purpose is to build a portfolio page, that includes some sort of content generation.

But more important, we need to define a purpose for the page, since every good landing page should guide the visitors to a single action we want them to do.

For now, the call to action I'd like to implement is a contact action; so I can spark the collaboration I've talked about in previous posts.

Also, I wanted to integrate Prismic.io headless CMS, so here's the list of tasks to address for a simple first version:

Integrate Prismic.io

This requires installation, and implementing a few components to display the posts list and the actual content.

I'm not gonna dig into the details, but Prismic provides an API you can integrate to, so you can list and filter posts and obtain the actual content from a post, so you decide how to render it; but also you have

This required the implementation of two components:

  1. The "blog" route handler, to show a list of recent posts.
  2. A generic component that will handle whatever is thrown at /blog/[slug] and try to render a post, based on the provided slug.

Prismic also provides sample code to start building, so you don't have to start from scratch; but keep in mind that you'll need a bit of personalization (like adding styles for bullet headlines, bullet points, etc) to be able to actually display your first post; since Tailwind resets most of the styling to leave you with pretty much vanilla HTML tags.

Add the color palette variables

I headed over to my globals.css file, to add variables for all the colors I've generated using Coolors.co. I've actually added a darker shade to use as the background of my portfolio, since I wanted to go dark mode.

Adding a description and call to action

We'll keep it simple, with a bio that states my current career state and a single action to let visitors contact me. We can customize it later.

This way, while simple, we have a link we can share and keep working on improving the site, by asking for feedback and drawing from inspiration from across the internet.

The first version of the jpgc.tech website, with just a call to action to Contact me

Other minor stuff

  • I integrated the HugeIcons library, since it has a great free selection.
  • I've set-up a custom domain, from Namecheap; for the website but also to have a unique email address I can use to track contact attempts that came right from the landing page.
  • I've published my Resume as a Google Drive file, so anyone interested can see/download it. An important part, is that I'm using Google Drive's document versions, so I can replace the file with a newer version, without changing the link already added into the page.

Pending tasks

I've talked about how we're using production-grade tools out of the box, but we still need to address a few concerns before calling a site like this "production ready":

  • Setting up different environments (right now, everything goes straight into production). We don't need any complex git branch setup, since we're building this solo; but a test environment it's a welcome addition.
  • Improve SEO and make sure all the content we're creating is search-engine friendly.
  • Handle translations. While the site will remain in English, translation libraries often provide a good way to handle text, so it's not hardcoded inside the HTML, which is such a pain to maintain.
  • Add a proper components library, that speeds up further development; so we don't have to worry about implementing menus, auto-completes, tables, etc.
  • Add analytics, so we can assess whether the portfolio page is fulfilling its purpose and understand the behavior of the visitors (or if there's any visitors at all!
  • Implement the actual portfolio! The goal is to also experiment and build something that's worth sharing.
  • Etc.

One last thing, I've ran a Lighthouse test, and the results are great so far:

Lighthouse test results for the first version of jpgc.tech with 97 overall score

The challenge is to keep those scores up.

💡Pitfall: I actually had to inject the the single image's URL using a JS variable instead of adding it straight into the HTML, so it was delivered through CDN (you can tell the image source by inspecting the URL it came from and checking whether it has some sort of hash as part of URL and it's not referencing the same path as defined by your code's folder structure).

That's it! after some hard work, we have our first version deployed, but there's still a lot to do.