Logo for ammarahmed.ca
BackTech
How it’s made: ammarahmed.ca cover image
Oct 26, 2022

How it’s made: ammarahmed.ca

#Backend
#Frontend
#API
#UI/UX

Like most, my first-ever project in the web development field was to create a portfolio website for myself. At first, it started with straight HTML and CSS, progressed into adding JavaScript and frameworks like Bootstrap, and then moved on to React.

I would find myself re-designing and re-factoring my website countless times for various reasons: I didn’t like the design anymore, I wanted to add more features, or just because I was bored. However, the main culprit as to why I found myself re-designing my website so many times was because I was using it as a tool to learn. I did not have enough experience in web dev to create a website that was designed well so I would constantly be re-doing my website to learn new technologies and languages.

After countless design iterations and some professional experience in the web dev field, I felt confident enough to embark on a personal website to end all personal websites (hopefully...). I set out to construct a website that is designed deliberately and thoughtfully and is implemented with modern technologies that will allow to me add any features I want without having to do a complete re-design.

Design Considerations

To start, I want to outline the design considerations I had in mind before starting the development of the site.

Content Management

As I had become quite proficient in full-stack development, I wanted to create a portfolio that acts sort of like a CMS (content management system). The rationale behind this stemmed from an annoyance I had with my previous sites; whenever I wanted to add a new project or work experience to the site, I would have to go back in the code and manually code them in. For this reason, I wanted a way to add data to the site from the site itself or without having to go back into the code.

At first, I thought of creating an interface for myself to create and edit the content on the website. However, while thinking this through, I had a realization. Most of my content editing and writing was done on Notion. So, wouldn’t it be easier if I could populate my website's content straight from Notion?

After some research, I found that Notion had recently released its developer API. I found out that I could use this API to read content from my Notion account in many ways. From this, I decided that it would be best for me to use Notion as the database for my content and the API to connect it to my website.

One consideration that most will come to naturally is that Notion is not a very efficient database, however, for my purposes, it would be sufficient. The amount of data would not be large nor would it require read or write efficiency.

Stack

The next design consideration would be the stack I’d be using for this website. As I had tons of experience with React, the front-end choice was easy. However, in the backend, I had a few options. I had a lot of experience creating apps for fun using the MERN (MongoDB, Express, React, and Node) stack, so, I was very familiar with creating REST APIs with Express.

However, I had recently started to learn GraphQL and found that it was a more elegant and simple method for APIs as compared to REST APIs. There was also the bonus of static typing (defining data types explicitly to reduce errors). For this reason, I decided to go with GraphQL, Node.js, and Apollo-Express for the backend. As mentioned previously, the database being used is Notion.

Therefore, the stack that was planned out was:

  • React with TypeScript (frontend)
    • GraphQL with Apollo-Express and Node.js with TypeScript (backend)
      • Notion (database)

        Hosting

        After this, I had to think about hosting the website. As my website at the time of this design was already hosted using Google Firebase, I decided it would be easiest to keep this the same. Google Firebase allows free hosting for projects like this and I had already set up auto-deploying with GitHub production branch pushes as well as connected a personal domain, so, I didn’t have any reason to change the frontend hosting.

        For the backend, while I had prior experience using Heroku to deploy personal Node.js projects, they had recently removed their free tier and made all plans paid. While I love Heroku's functionality and I don't mind paying for good services, the complete removal of the free tier is something I am personally opposed to. Many young developers and developers from underprivileged societies are not able to pay for these services and Heroku removing their free tier excludes these groups heavily. For this reason, I've decided to boycott Heroku.

        As an alternative, I chose to use Fly.io. They share similar features with Heroku for cloud hosting and their documentation was simple enough for me to set up my backend hosting quickly and easily. I was also able to set up auto-deployment quite easily. They also have a very generous free tier which is also a plus.

        UI

        Before this design, I would create all UI with vanilla HTML and CSS with components created by myself for all my React projects. However, this time around, I wanted to try a more rigorous and foolproof UI approach. I wanted to use some type of React UI framework such as Material UI, Bootstrap for React, or something similar.

        While conducting my research, I came across Chakra UI. I found that their components were much more modern and good-looking as compared to Material UI. I also saw that they had a complete implementation for dark and light modes built-in and they also prioritized accessibility. While I know that Material UI can be made to look like anything with their styling options, I did not want to be spending a lot of time messing around with styles and found that Chakra UI looked good right out of the box, so, I decided to go with this.

        Update: May 2024

        As some may notice, I’ve recently changed my website design a little. The main design components are the same, however, there is a slightly more modern look to all of the components. This is because I decided to switch from ChakraUI to TailwindCSS and NextUI.

        I came across NextUI and loved it’s look and animations, so, I decided to re-design using this. It was not too difficult as I was simply converting an already made design.

        UI Design

        In terms of the actual UI design of the website, I wanted to go for a neutral look. I did not want it to be very extravagant but I also wanted it to look good. For this reason, I decided to go with a black-and-white look with a singular, bold primary color. The primary color I chose was a deep purple color to be used in conjunction with a lighter blue color to have some gradient effects sprinkled here and there.

        Layout

        As for the layout of the website, I wanted 3 pages: Home, About, and Blog. The home page would consist of a hero landing at the top. After scrolling down, users would find a list of my projects and their descriptions. Scrolling down a little more, they find my work experiences. The reason for this was that I wanted to have the most relevant information for employers right on the home page so they wouldn’t have to go digging.

        Later on, I decided to add a skill section on the home page as well consisting of radar charts for different categories of skills visualizing my competencies in them.

        Language

        For a project of this size, I decided to go with TypeScript instead of JavaScript. This is mainly due to the decrease in debugging time that TypeScript provides. As this project has so many different components, TypeScript allows for self-documentation of how everything works. I knew that I’d be spending a long time creating this website and I find that reading back old code that is statically-typed is much easier to understand as compared to dynamically-typed code (JavaScript).

        For the front end, using TypeScript is not much different than using JavaScript as React has built-in support for both, however, on the backend, I decided to implement a library that I had not used very much before called TypeGraphQL. This allows for creating GraphQL servers using class definititions and TypeScript decorators. With a JavaScript implementation, you would have to write out resolvers and then also define a GraphQL schema for the types. With TypeGraphQL all you have to do is write classes and the schema is auto-generated as you define it. This greatly decreased development time as well as created much cleaner and more readable code.

        Implementation

        As I have a lot more fun with backend development, I started with the server and API configuration. I had a few major tasks for the backend server implementation:

        1. Setting up the GraphQL server
          1. Connecting the Notion API
            1. Designing my Notion “database”
              1. Parsing Notion responses to fit my needs
                1. Creating GraphQL endpoints

                  Once all this was complete, it was time to move to the front end. Major tasks related to the front end included: