Making a Social Media App
Tags: webdev, react, nextjs, programming
Published: 2022-10-12 16:13:24

Hey, I'm Tanvir Bhachu. I was really bored one day so I decided to make a social media platform. So here's an article on how I did it.

Before we start, here's a link to the completed project: Veritas

## Part 1: The Foundation
First I needed to figure out how I wanted to approach the project. I obviously opted for React and NextJS since that's my main stack. I didn't want to build the whole social media infrastructure so I chose Sanity CMS to handle all the post content. For chat, I was thinking of making an actual clone from Instagram but services for integrating chat are extremely expensive. So I instead made the whole chat myself using MongoDB. Since I was using MongoDB anyway, I used it for user authentication.

## Part 2: Setting Up the Backend
I tackled Sanity first. I created the schemas, essentially planning out how all the data is going to be structured. This wasn't very difficult at all but it was the first step.

## Part 3: The Authentication
There are 3 main parts to the login page. The register part takes in a user's email, username and password and creates a user in MongoDB. Before a user is created, it'll check whether or not a user with the same email or username exists. The login part takes in a person's username and password. Then it'll check if that user exists in Sanity because that's where the main details are and the user in Sanity is used as a reference when creating a post. If it doesn't, it'll create a user with some predefined values otherwise it'll set the user data to the local storage.

The forgot password mechanic works by entering a person's email and password correctly. If so, it'll send an email to them with their password. I used an email I don't normally use so it might go to spam but it works.

## Part 4: How the actual app works
The entire application is on one page. It uses router queries to see what component should be displayed. I built a 'capsule' that holds all the components. The navigation and data fetching is done at the top level so the state can persist even if the page changes. If you're on posts and you click on the user profile, the data will be available immediately because of this.

Using Tailwind, dark mode is handled simply by adding the classname 'dark' if the local storage has dark mode = 'true'. I also used some npm packages such as "react-toastify" for the notifications and "react-loader-spinner" for the loading screens.

## Part 5: User Profile
Once you pass the login, you get to the actual app. I started with the user details because it's displaying data I already have. So the page takes the Sanity data from local storage from when the user logged in. Next, I add the ability to edit your profile picture, cover image and bio. This takes in some inputs and edits the user data in Sanity using the user's id.

## Part 6: Showing Posts
All the data is fetched using a couple of useEffect hooks. It uses some predefined queries to fetch certain data from Sanity which is especially helpful with getting posts only from the current user. I used a package called "react-responsive-masonry" to create a masonry layout. Then I mapped the array of posts from Sanity and added those posts to the layout.

## Part 7: Creating Posts
When you add an image to upload, it creates an asset in Sanity but it doesn't belong to any document yet. After adding the title and description for your post, it'll create a document for your post. Once you go back to the home page or the user profile, it'll rerun the fetch function to update the list of posts to include your post.

The deletion of posts simply runs a function to find a post using its id and to delete using a client library from Sanity.

## Part 8: Creating a chat system
So I created a separate collection in MongoDB just for chat messages. I could create chat rooms by creating maybe a group id and then only showing messages with the correct group id. However, I just wanted to show a prototype of what a chat system would look like. I might choose to create that functionality but it may push the capabilities of MongoDB, at least the free tier which is what I used. I also didn't want a massive number of messages. It's very painful having to go delete every message individually. So I added something called a TTL index. This allows me to automatically delete any message sent after 3 days. On the client side, a function is run every 5 seconds to check for new messages.

Also, MongoDB is not built for chat systems. In a real-world scenario, you would probably want to use WebSockets to get real-time chats and Supabase for the database.

## Part 9: The Shopping Tab
I wanted to recreate the feel of Instagram so I added a shopping tab. This is pretty basic and honestly, a little too basic for me so I might change it a bit. I created a JSON file that has all the data for each product. This is simply because I didn't want a huge file so mapping over a JSON file makes management a lot easier. I create an Amazon Affiliates account and put links to products that were either really popular or that I personally bought. And that's about it.

## Part 10: The Future
This is a stable version of the platform, good enough to show as a portfolio project. But I want to add the ability to like and comment, create group filtered chat groups, make the shopping tab much better and also add the ability to view other people's accounts.

Overall, it was a very good project to work on. It feels nice and fast and it has functionality. Feel free to check it out, all you need to do is create an account.