Pixel Chat
Purpose & Planning
The primary purpose of Pixel Chat is to enable instant messaging between users whom can also share gifs, like posts or change their profile avatar. Each user creates a profile in order to, allow storage and retrieval of previous messages upon login, therefore I needed to use a database to store user credentials and protect passwords. This meant protected routes were required within the app to authenticate valid users.
Taking app requirements into consideration while planning led me to use the mongoose ORM with Mongo DB. I needed to store users and message models that interacted, therefore built my schema with a join between the two. I managed my work flow with a Trello kanban board and used Figma for prototyping the app.
Stack
- React
- Node.js & Express.js
- MongoDB
- Tailwind CSS
- Netlify
The MERN stack was used, with socket IO in my backend API allowing instant messages between users. While creation of a profile, is handled with Mongo DB, & bcrypt for storage, encryption and authentication of credentials. Additionally user authorization with JWT enables a login to persist across multiple requests.
The API was built in Node.js giving full C.R.U.D functionality that allows users messages / profile to be updated or deleted. For styling I've chosen Tailwind because its utility classes enabled me to match my Figma prototype quickly and meant improved style readability inside JSX. While Netlify & Render were used for deployment and linked with GitHub repos to enable continuous integration.
Features & Challenges
Like / Laugh reactions
I wanted users to be able to react to messages. This was challenging as it required updating the senders message in real time as well as messages stored in the database while additionally only rendering reactions to a sender if the receiver clicked a reaction button.
To implement this feature, I created a function that emitted reactions to the socket in real time and updated the specific message in the database with a PUT request and mongo query. To ensure senders only see icons on their message when reacted upon, I used conditional rendering in React with hooks managing state of the reactions.
Authorization with JWT
In order to ensure that only authorized users could access a profile I needed to create routes that were private and protect CRUD requests to the API.
To fulfill this I've used a JSON web token, generated upon a successful login or registration. This is then stored in local storage, allowing access for client requests to the server. I further use this to create private and public route components with React router, authenticated by the token in local storage. This ensures a user can only access authorized pages in the app.
Bad Word Regex
Chat apps are prone to inappropriate / abusive messages therefore I've decided to implement a parser built with regex to replace any profanities.
To accomplish this I've used an array of common inappropriate words and created a regex constructor which iterates the array matching against dynamic content from user input. I've composed this with the JS replace method to match and swap the bad words with a crossed out alternative.
What I learned
Overall, this project enhanced my skills in full-stack development, creating real-time communication, without manual refreshing using React, Socket.io, and Node.js.
Making API routes for C.R.U.D functionality among users / messages, storing them in a database, and retrieving message history between users, strengthened my knowledge of RESTful API principles and HTTP requests using the Axios library.
Additionally I improved my knowledge of accessibility, testing the app using the VoiceOver screen reader and Axe Dev Tools chrome extension to ensure I met WCAG standards on accessibility.