19 August 2020
How I created a full-stack portfolio website and a custom CMS
I already had a portfolio website, but it was boring, non-responsive and generally ugly. With this in mind, I set out to learn some back-end technology and create a portfolio website that people would hopefully enjoy exploring. I also decided to create a blog (as you are now reading) and a dynamic portfolio that contains projects, tools, and experience. This resulted in me also creating a custom CMS (content management system) so I can easily update content on my website whenever I want – without having to hardcode it into the HTML.


“SquareSheep Studios”.

Although this is an incredibly random name for a portfolio website, I wanted to come up with something that is unique and memorable. Hopefully, people coming to this site will leave with something in mind – as sheep don’t tend to do much worthy of a portfolio.

Something I get asked a lot is why it is called “SquareSheep Studios” if it is a one-man studio. I made this decision because of all the places it has operated in, and where the creativity has taken place. I have been very lucky to have lived in 3 different countries and 2 different continents up to this point – and many different locations within each of those – and so ever since I created this tiny little studio, it has travelled all of those places with me.

Planning Development

The first step in the process of creating a full-stack website is to identify the technology that you want to use, thus I did some research online and landed upon Node.js, Express and MongoDB. Very new to this side of development, I found a fantastic course on Udemy where I obtained a great foundation of knowledge on this new technology. The course is called “The Web Developer’s Bootcamp”, and I highly recommend you check it out if you are interested in learning this technology.<

I proceeded to begin making designs of what features I wanted the site to have, how it would look and how I wanted users to interact with it. I had brainstormed ideas and features I wanted in my head and used Photoshop to design how I wanted each of these pages to look. Once I had a solid foundation, I jumped straight in to programming it.

The mockups of how I wanted the website to look


As I briefly mentioned before, I used Node.js as the back-end technology. Node.js essentially allows you to write JavaScript on server side – which was great as I was very familiar with it. Using Node.js, there were other technologies I used to bring my website to life, such as Express – which is package that allows you to handle all of the routing and web server requests. As I wanted to implement a portfolio containing projects, tools, and experiences – and a blog – I was going to need a database as well.

I chose to use a database so that it would be easy to update content through a custom CMS (more on that later) and so that I could access information across different parts of the website whilst only having to store information in one place. It would also later allow me to introduce features such as newsletter signups and automated email notifications.

In order to accomplish and develop a database system – I used MongoDB, a NoSQL database technology that I can use in parallel with Node.js through the use of Mongoose, which is a package used with Node.js to manipulate and communicate with MongoDB databases.

After identifying what I was going to work with, I wrote the basic back-end framework that enabled the website to become functional and started to get to work on the front-end.

The order in which I planned to complete different tasks is something I gave a lot of thought before I set off on pursuing this project. If I were going to build a web app, then I would have worked on its functionality first, to make sure users could accomplish what they set out to do. However, considering this is a portfolio website and presentation was my main focus – the front-end was my priority to begin with. Working with the designs I had created earlier; I wrote my HTML and CSS for all of the pages on the website. I roughly stuck to the mockups I had created, however made some changes here and there to accompany responsive design and changes to aesthetics that I thought were better than originally planned. When it comes to the front-end, I carefully considered which end I would build the site up from – mobile to desktop, or vice versa? Once again, were I going to build a productivity app, I would start with mobile, as this would allow me to introduce elements as I went up in screen size – meaning I wouldn’t have to remove and squash things as I worked down from desktop to mobile. However, my portfolio site is more focused on people visiting it on desktops, this is because many of my projects are not aimed at mobile and it is something that people visit to really explore and discover. Although – that being said – I of course made it responsive and it still contains all of the main content that desktop has as well.

The front-end designs

Developing the CMS

As this is something only I should see, and it is something purely focused on its functionality – I of course prioritised the back-end database communication rather than the front-end design. Using Mongoose (to communicate with the MongoDB database), I started by setting up the schemas for the different elements that were going to be stored in the database. There are three different schemas for the portfolio; project, tool, experience – and then for the blog there is just one – the entry. There is also a schema for the newsletter signups which just contains a single string for the user’s email.

I designed some simple UI for me to navigate between the different sections, and then began work on the functionality. I started by implementing the tool section of the portfolio. This is because this is a dependency for the project section.

I designed the tool upload so that I can copy a Font Awesome icon code so I can refer to tools via their logos when I don’t have space for detailed information and have to squeeze everything in a small space. Once this was done, I was able to start work on the main attraction of my website – the project section. Other than the basic information like the name and the description, each project has a link to a local destination that contains the actual project files, and also an ID link that is how the back-end identifies what it is looking for in the database. I chose not to use the built in Mongoose ID to identify projects, as it is what’s displayed in the URL and helps SEO to have it something relevant to the subject. The most challenging part of creating the project part of the database was displaying all of the tools I have logged on the website. Essentially – when creating a new project – a list of checkboxes are displayed each with a label representing their respected tool, and depending on which ones are selected, determine what icons for different technologies show up when displaying a project on the website. The final part of the portfolio is the experiences – which were incredibly simple after doing the tools and projects as it is just a few strings that need to be stored. Once I had all of these implemented, I needed to be able to edit and delete them from this CMS as well – which was really easy because of the framework I had already set up. I was able to copy over the same form for the upload section and essentially just turn the POST request into a PUT request. Then in the edit form I also added a delete button at the top which of course sends a DELETE request. However because HTML only support GET and POST requests (for some strange reason), I decided to use an NPM package called method-override which allows me to make any request that I want. This does not change the functionality and the edit form could have been done using a POST request, however it was important that I kept this system as RESTful as possible. I also made sure to make a section where I display all of the different projects, tools, and experiences directly in the CMS- and clicking on one is how I navigate to the edit form.

Now that the portfolio database integration was complete, I just had the blog to do. Which actually turned out to be the most challenging part of this whole project! The only reason for this is because of a text-editor that I had to make. Actually saving the information was simple, however this system to create dynamic content turned out to be very challenging, and I ended up having to just create a text-area where I input the different parts of the blog as HTML elements. Although I did get part of the way with creating a dynamic text editor – it just wasn’t working the way I wanted, and so I decided to go for the simple solution. However this is definitely something I would like to learn more about in the future.

As storing high-resolution images can quickly eat up a lot of storage on your database, I decided to store the images locally on the website and just input the name of the directory in the database. This means that I can refer to the images in the blog entry without having to actually store them on the database. By inputting the directory, I don’t have to give a full path to the images and can just refer to their file names when referencing them in the blog post.

There was just one small task with the database left to do – however it is incredibly simple – a newsletter signup. This is the only POST request to the database coming from the actual website. I also implemented a small middleware that checks if the email address is already signed up – and made a DELETE request for people to unsubscribe as well.

I decided I wanted the newsletter to send out updates and notifications to people wherever I released a new project or publish a new blog post on the website. For this, I did some research and found that I wanted to use Nodemailer which is of course an NPM package that helps you to communicate with email clients and actually send out emails. This resulted in me creating two custom domain emails for – one for email automation, and one for physical email communication. Every time I upload a new project or post a new blog post, I use Nodemailer to loop through all of the newsletter signups and send an email by filling in a dynamic HTML template I created with the new project or blog post. You can sign up to the newsletter here.

Now that all of the database integration was done, hooking it up to my website was easy – just using environment variables with the link to the public database (using MongoDB Atlas) and ejs to dynamically create HTML elements and determine how I want the website to retrieve and display information from the database.

The back-end app


This has been such a fantastic learning experience, and I have really enjoyed learning so many new aspects to web development, and how to make some really awesome features; like a blog, newsletter – and of course a dynamic portfolio.

I highly encourage anyone reading this that is interesting in web development to investigate and play around with all of these amazing tools and technologies. Node.js in particular is great because of NPM – if there is a feature you want to implement, then there is probably a way you will be able to do it by finding a package on this amazing platform.

I hope you enjoyed learning a bit about my time and experiences embarking on this awesome project. Happy developing!