Table of Contents
Look at the project's live demonstration: Chirpy web application
Users can share their thoughts with other users on the social media platform named Chirpy by using this application. Chirpy is a server-side rendering, full-stack web application written in TypeScript and Next.js 13. It makes use of Clerk as the provider of authentication and MongoDB as the database. It uploads pictures to the cloud via UploadThing as well. Tailwind CSS and Shadcn components are utilized for styling the application.
Our objective is to develop "Chirpy," an application that addresses accessibility concerns and goes above and beyond to make sure that all users, regardless of their abilities or impairments, feel not only accommodated but also genuinely welcomed. We are committed to developing a platform where inclusion is the norm and understand how crucial it is to make it user-friendly for everyone.
Folder Structure
chirpy
ββ app
β ββ (auth)
β β ββ layout.tsx
β β ββ onboarding
β β β ββ page.tsx
β β ββ sign-in
β β β ββ [[...sign-in]]
β β β ββ page.tsx
β β ββ sign-up
β β ββ [[...sign-up]]
β β ββ page.tsx
β ββ (root)
β β ββ activity
β β β ββ page.tsx
β β ββ chirp
β β β ββ reactions
β β β β ββ [id]
β β β β ββ page.tsx
β β β ββ [id]
β β β ββ page.tsx
β β ββ circles
β β β ββ page.tsx
β β β ββ [id]
β β β ββ page.tsx
β β ββ create-chirp
β β β ββ page.tsx
β β ββ edit-chirp
β β β ββ [id]
β β β ββ page.tsx
β β ββ layout.tsx
β β ββ page.tsx
β β ββ profile
β β β ββ edit
β β β β ββ page.tsx
β β β ββ [id]
β β β ββ page.tsx
β β ββ search
β β ββ page.tsx
β ββ api
β β ββ uploadthing
β β β ββ core.ts
β β β ββ route.ts
β β ββ webhook
β β ββ clerk
β β ββ route.ts
β ββ favicon_io.zip
β ββ globals.css
β ββ icon.ico
ββ components
β ββ atoms
β β ββ EditChirp.tsx
β β ββ FollowUser.tsx
β β ββ ReactChirp.tsx
β ββ cards
β β ββ ChirpCard.tsx
β β ββ CircleCard.tsx
β β ββ UserCard.tsx
β ββ forms
β β ββ AccountProfile.tsx
β β ββ Comment.tsx
β β ββ DeleteChirp.tsx
β β ββ PostChirp.tsx
β ββ shared
β β ββ Bottombar.tsx
β β ββ ChirpsTab.tsx
β β ββ LeftSidebar.tsx
β β ββ Pagination.tsx
β β ββ ProfileHeader.tsx
β β ββ RightSidebar.tsx
β β ββ Searchbar.tsx
β β ββ SearchBarCircles.tsx
β β ββ Topbar.tsx
β ββ ui
β ββ button.tsx
β ββ form.tsx
β ββ input.tsx
β ββ label.tsx
β ββ tabs.tsx
β ββ textarea.tsx
ββ components.json
ββ constants
β ββ index.js
ββ lib
β ββ actions
β β ββ chirp.actions.ts
β β ββ circle.actions.ts
β β ββ user.actions.ts
β ββ models
β β ββ chirp.model.ts
β β ββ circle.model.ts
β β ββ user.model.ts
β ββ mongoose.ts
β ββ uploadthing.ts
β ββ utils.ts
β ββ validations
β ββ chirp.ts
β ββ user.ts
ββ middleware.ts
ββ next.config.js
ββ package-lock.json
ββ package.json
ββ postcss.config.js
ββ public
β ββ assets
β β ββ user.svg
β ββ next.svg
β ββ vercel.svg
ββ README.md
ββ tailwind.config.js
ββ tsconfig.json
Look at each folder cautiously to see what they contain
(auth)/
- (root)/
- (api)/
In the app directory, nested folders are normally mapped to URL paths. However, you can mark a folder as a Route Group to prevent the folder from being included in the route's URL path.
This allows you to organize your route segments and project files into logical groups without affecting the URL path structure.
For example,
atoms/
- cards/
- forms/
- shared/
- ui/
The components directory contains all the components used in the application. The components are grouped into atoms, cards, forms, shared and ui.
the ui
folder generated by shadcn/ui
package and contains all the required shadcn components that used in the application.
index.js
This is a JavaScript code contains all the constants used in the application, specifically the Sidebar Navigation (sidebarLinks
), Profile Tabs (profileTabs
) and Circle Tabs (circleTabs
) constants.
actions/
- models/
- validations/
- mongoose.ts
- uploadthing.ts
- utils.ts
The lib folder holds crucial components for Chirpy App:
- actions: Manage actions for Circle, Chirp, and User entities using Mongoose for database interaction.
- models: Define mongoose schemas for Circle, Chirp, and User entities.
- validations: Provide validation schemas with Zod for Chirp and User data.
- mongoose.ts: Establishes and manages MongoDB connections for the application.
- uploadthing.ts: Offers a React utility for simplified file uploads to UploadThing.
- utils.ts: Contains various reusable utility functions.
assets/
- next.svg
- vercel.svg
The public directory contains the media used in the application. The assets folder contains all the images used in the application.
Chirpy is built using the following technologies:
- TypeScript: TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
- Next.js 13: Next.js is a React framework for building server-side rendered and statically generated web applications.
- Tailwind CSS: Tailwind CSS is a utility-first CSS framework for rapidly building custom user interfaces.
- Shadcn: Shadcn is a collection of Tailwind CSS components.
- Clerk: Clerk is a developer-first authentication API that handles all the logic for user sign up, sign in, and more.
- UploadThing: UploadThing is a simple, fast, and reliable file uploader for your website.
- MongoDB: MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.
- Mongoose: Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment.
- Zod: Zod is a TypeScript-first schema declaration and validation library.
- svix: Svix is a webhook proxy that allows you to receive webhooks locally.
- emoji-mart: Emoji Mart is a customizable. emoji picker HTML component for the web.
- Vercel: Vercel is a cloud platform for frontend developers, providing the frameworks, workflows, and infrastructure to build a faster, more personalized Web.
To get this project up and running in your development environment, follow these step-by-step instructions.
In order to install and run this project locally, you would need to have the following installed on your local machine.
Step 0:
Create .env.local
file and it should be located alongside with .gitignore, next.config.js & etc.
Note CLERK_PUBLISHABLE_KEY
and CLERK_SECRET_KEY
environment variables in .env.local
file. Also, the different URLs for the Clerk sign-in, sign-up, after sign-in and after sign-up pages.
Note MONGODB_URL
environment variable in .env.local
file located in server
folder.
Note UPLOADTHING_SECRET
and UPLOADTHING_APP_ID
environment variables in .env.local
file.
After following all the instructions above, we'll want to create a new webhook on Clerk. To do this, go to the Clerk Dashboard, click on the "Webhooks" tab, and then click "Add Endpoint". For the Endpoint URL, enter http://<PASTE-YOUR-LINK-HERE>/api/webhook/clerk
. For the evetnts, select the "organization", "organizationDomain", "organizationInvitation" and "organizationMembership". Then click "Create" to create the webhook. get the signing secret and set it as CLERK_WEBHOOK_SECRET
environment variable in .env.local
file.
Step 1:
Download or clone this repo by using the link below:
git clone https://github.com/LeinahI/Chirpy.git
Step 2:
Execute the following command in the root directory of the downloaded repo in order to install dependencies:
npm install
Step 3:
Execute the following command in order to run the development server locally:
npm run dev
Step 4:
Open http://localhost:3000 with your browser to see the result.
All scripts are defined in the package.json
file. Here is a list of all scripts:
Script | Action |
---|---|
npm install |
Installs dependencies |
npm run dev |
Starts local dev server at localhost:3000 |
npm run build |
Build your production site to ./dist/ |
npm run start |
Start your production site locally |
npm run lint |
Run ESLint |
Environment variables[^10] can be used for configuration. They must be set before running the app.
Environment variables are variables that are set in the operating system or shell, typically used to configure programs.
Chirpy uses Clerk, UploadThing, and MongoDB as external services. You need to create an account on each of these services and get the required credentials to run the app.
Create a .env.local
file in the root directory of the project and add the following environment variables:
//MongoDB
MONGODB_URL=<MONGODB_URL>
//ClerkApi
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=<CLERK_PUBLISHABLE_KEY>
CLERK_SECRET_KEY=<CLERK_SECRET_KEY>
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/onboarding
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/
//ClerkApi_Signing-Secret
NEXT_CLERK_WEBHOOK_SECRET=<CLERK_WEBHOOK_SECRET>
//UploadThing
UPLOADTHING_SECRET=<UPLOADTHING_SECRET>
UPLOADTHING_APP_ID=<UPLOADTHING_APP_ID>
You can create an optimized production build with the following command:
npm run build
The easiest way to deploy this Next.js app is to use the Vercel Platform.
Chirpy web application comes with the following features:
- CRUD Chirps, Communities and Profiles
- Like Chirps
- Multi-level Comment Chirps
- Follow Profiles
- Search Profiles and Circles
- Activity Feed (Likes, Comments, Follows)
- Explore Feed (Chirps of Followed Profiles)
- Profile Tabs (Chirps, Followers, Following)
- Community Tabs (Chirps, Members)
- Chirp Likes Page (Profiles that liked a Chirp)
- Post and Comment Emoji via emoji-mart
In terms of technical features, Chirpy web application comes with the following features:
- TypeScripted Codebase with Next.js
- Authentication with Clerk
- User Management with Clerk
- Organization Management with Clerk
- File Upload with UploadThing
- Server Side Rendering with Next.js
- MongoDB Database
- Mongoose ODM
- Zod Validation
- Shadcn Components
- Tailwind CSS
- Svix Webhook Proxy
- Vercel Deployment
- Not implementing utfs.io on next.config.js
//Solution
remotePatterns: [
...
,{
protocol: "https",
hostname: "utfs.io",
},
],
- Activity Tab = Hydration errors due to interactive content of
<Link>... <Link>...<Link/>...</Link>
this occurence.
//This error occurs on app/(root)/activity/page.tsx because of href={`/profile/${author.id}`} is undefined
//Solution
import dynamic from "next/dynamic";
const DynamicLink = dynamic(() => import("next/link"), { ssr: false });
// all <Link> tag from next/link should change into DynamicLink
<DynamicLink
key={activity._id}
href={`${
(activity.parentId && `/chirp/${activity.parentId}`) ||
`/profile/${activity.author.id}`
}`}>
...
<DynamicLink key={author._id} href={`/profile/${author.id}`}>
<span className="text-primary-500">{author.name}</span>
</DynamicLink>
- Activity Tab = When the same person liked your 2 different post but it only shows a same single link.
//at user.actions.ts getActivity()
const reactionsData = reactions.map(
(reaction: {
user: { toString: () => any };
_id: any; /* NEW */
createdAt: any;
}) => {
const reactingUser = reactionsUsers.find(
(user) => user._id.toString() === reaction.user.toString()
);
if (reactingUser._id.equals(userId)) return null;
const parentChirp = userChirps.find((chirp) => /* NEW */
chirp.reactions.some((r: { equals: (arg0: any) => any }) =>
r.equals(reaction._id)
)
);
if (!parentChirp) return null; /* NEW */
return {
author: {
name: reactingUser.name,
username: reactingUser.username,
image: reactingUser.image,
_id: reactingUser._id,
id: reactingUser.id,
},
createdAt: reaction.createdAt,
parentId: parentChirp._id.toString(), /* Modified */
activityType: "reaction",
};
}
);
const replies = await Chirp.find({ /* Modified and reaction to concat follow removed */
_id: { $in: childChirpIds },
author: { $ne: userId },
}).populate({
path: "author",
model: User,
select: "name username image id _id",
});
const activity = [...replies, ...reactionsData, ...followersData]
.filter((item) => item !== null)
.sort((a, b) => b.createdAt - a.createdAt);
Chirpy is open source software licensed as MIT and is free to use β See LICENSE for more details.
The following people assisted me throughout this project and made it possible, for which I am grateful.:
β’ JavaScript Mastery. (2023, August 4). Build and deploy a full stack MERN Next.js 14 threads app | React, Next JS, TypeScript, MongoDB. Retrieved from https://www.youtube.com/watch?v=O5cmLDVTgAs
β’ Ladunjexa. (2023). GitHub - ladunjexa/nextjs13-threads: Threads, Next.js 13 app that skyrocketed to 100 million sign-ups in less than 5 days. Retrieved from https://github.com/ladunjexa/nextjs13-threads