As part of building side projects to fill out my front-end portfolio I recently built a full stack serverless e-commerce site. I have always enjoyed building larger applications and I thought I would build my biggest project yet.
One of my first personal projects was a small site for a fictional brewery company. It had a home page, products page, contact page and a small product store. The products store was more of a to-do list than a real e-commerce store. You could add and remove items but there was no checkout process or payments.
Ever since then I was determined to build a full e-commerce site with all the bells and whistles. And so I did. This is the home screen of 'Kieran's Coffee Collection' in the light color theme 👇.
It is far from perfect which you might see if you look at the code 😅. But it is finished and working and I'm proud that I was able to get to the end. A lot of the points I will soon talk about are the struggles I encountered along the way because I think it is important to reflect on what we can improve on.
Here is the live version of the site 👉 Kieran's Coffee Collection
and here is the code 👉 Github repo
This is not a walkthrough of the project. You wont see any code but instead it is an overview of my experiences and failings so that it might help you.
I am open to writing about the technical side of the project including code and how I built the site. If that is something that interests you then let me know in the comments or alternatively check out the repo.
I learned a hell of a lot during this project so why not share it you. Let's go!
- So what is Kieran's Coffee Collection?
- What I learned and how it might help you
- 😍 I love Next.js
- 😕 Caching is tricky
- 😃 The back-end setup of Hasura, Auth0 and GraphCMS was great
- 🤔 Take time out to think through problems
- 😮 It is easy to forget about testing but we shouldn't
- 😉 This is the type of project where a component library like Chakra UI is perfect
- 😌 I need to spend more time with TypeScript
- Final thoughts
First a quick overview of the project. Kieran's Coffee Collection is a serveless e-commerce website built primarily with the React framework Next.js. The rest of the front-end stack includes the component Library ChakraUI, TypeScript and Apollo Client.
Since I'm primarily a front-end developer I wanted to simplify the backend as much as possible. User authentication is handled by Auth0 as a tried and trusted authenticator while Hasura graphql handles the creation and maintenance of the users database. Finally I have GraphCMS as a graphql based headless CMS to handle products and everything related to them.
My store in dark theme 👇
and the cart page also in the dark theme 👇
The primary features of the app include the following:
- e-commerce product store
- product sorting / filtering
- persistent cart / saved products
- user authentication / accounts
- checkout process
- user product reviews
- theme toggle
The shipping page in the checkout process 👇.
Now let's straight into my main takeaways 👏.
Next.js is great. I've now used it in a few different projects including my portfolio.
I love how it simplifies working with images, perfect for an e-commerce site where I'm working with a lot them.
I love how it makes routing and creating pages and dynamic routes so easy and fluid.
I love the TypeScript support which I'm starting to pick up.
I love the api routes that allow you to add some back-end functionality to your app which was perfect in my case. It meant I could easily integrate my authentication redirects, order webhooks and account details updates seamlessly.
If you have some experience with React and are looking for the next challenge I definitely recommend trying Next.js.
This is the first project where I really had to manage a cache. I had seen a popular computer science quote by Phil Karlton that says
There are only two hard things in Computer Science: cache invalidation and naming things.
This was my first project using Apollo Client for data fetching. If you've never used it before all you need to know is that it allows you to store the results of queries in a cache. I wanted to try it in previous projects but decided to go with other lighter weight options due to the limited amount of fetching I was doing in those projects. This time I went for it!
I found it to be great for client-side data fetching but I struggled at first when it came to managing the cache. As soon as I started to implement graphql mutations where I was forced to update the cache manually I found it tricky.
This in combination with component state updates and I was having a hard time in understanding why a mutation for a product review was causing 5 new reviews to appear on screen 😂.
But the more I dug into the documentation and took time out to think about problems the easier it became. So I ended up with two main takeways here.
First is don't underestimate cache management. Secondly the documentation is there for a reason so just read it!
The inspiration for this setup was provided by this article series Hasura Fit - By Jesse Martin.
Having previously built projects with Next.js and GraphCMS I was looking for a back-end stack that I could implement successfully as a front-end developer while still giving me user accounts and authorization etc.
I wanted a serveless setup where I could deploy the front-end to a CDN provided by Vercel but I would still have a dynamic app that could update when necessary.
👉🙂 Handling Users
Hasura provides us with instant grahql api's and acts as our 'backend as a service'. In minutes you can have a free Postgres database hosted on Heroku with api's to interact with it and I found using it to be a very pleasant developer experience.
The combination of Hasura and Auth0 was perfect for user authentication and accounts. For user sign-in I could just redirect users using next.js api routes to Auth0 and let them do the heavy lifting. On completion they would be redirected back to my site and by setting up some rules in Auth0, Hasura then handles the creation and maintenance of user accounts.
☕ Handling Products
I liked the separation between users and products included in the article. Having previously used GraphCMS in two separate projects I knew it would be perfect for handling data related to products. Setting up schemas and content is a breeze and I could incorporate mutations and webhooks when required. Similarly to Hasura it also has a free plan available which is great!
This is more of a general problem but I thought I'd mention it quickly. Before this project I was prone to frustration. Sitting for hours on end staring at the same problem hopelessly trying solutions that were destined to fail.
Now I have learned that stepping away from problems is often the best solution. If your stuck on an issue move on to another task and you'll end up thinking of a solution to your problem that involves a fraction of the code you would otherwise write.
I had to step away several times because of issues I was having especially when I was dealing with the Apollo cache. I was able to think out different solutions clearly and many of them I realized wouldn't work.
But some of them did and this saved me a lot of time instead of writing out the solution first and then realizing its no good.
I started off the project with the idea of testing as I go. Test Driven Development (TDD) is the process of starting by writing failing tests and then going about writing the code to satisfy the test and rinsing/repeating until satisfied.
It started off well but I soon got carried away with the building and testing was forgotten. If there is one takeaway that will stay with me into future projects it's that I'm going to try not to rush things and instead stick to the plan.
No one wants to be left writing tests after the project is done. It's not a great way of doing things and I'm going to be stricter with myself in the future.
For a large project like this with a lot of moving parts and large components Chakra UI was a life saver! I could build large, complex and accessible components in minutes leaving me more time to work on other parts of the app. This sidebar is one such example 👇.
I could build a sidebar like this with a background modal in no time and they're still extremely customizable. There are so many other examples of this. I've never found it so simple to add a light/dark theme toggle. You can then customize individual elements based on the color theme. It's great 😃.
Another example are these tabs located on each individual project page 👇.
If your thinking about building a larger project where you might need a lot of interactive components such as menus, drawers, tooltips, modals and much more then consider giving Chakra UI a go.
I have been learning TypeScript for the last couple of months. I though it would be a good skill to start learning now before I look for a job in the industry where I might need it. I'm comfortable with the basics but I found that I'm still unsure how to best use it when projects start to grow.
There are still too many times where I use the dreaded
any 😮 type or others that were sub-optimal effectively nullifying the benefits of TypeScript. I was also unsure of where a lot of the types and interfaces should live.
I would like to spend a little time organizing shared types into their own directory because at the moment it is not organized and it can be a waste of time tracking the origin of the file where the type is.
One of my focuses for the next month is going to be diving into the TypeScript documentation and do some more reading. I recently did something similar with git and now I'm much more comfortable with the popular version control system.
Although there are things I would have liked to have done differently I am very happy with the overall result. I accomplished my goal of building an online store for this fictional company where users can manage accounts, products and checkout out a cart with payments.
If you would like to see more about the technical side like how I integrated certain features than please let me know.
I'm always active over on twitter @Kieran6dev so come and say hi and if you liked the article please let me know. Thanks friends 👋.