Travel Diaries is a MERN stack web application where users can create, browse, update, and manage travel memories with images, locations, dates, and short diary descriptions.
https://traveldiaries.debarghya.org π
Travel memories are often scattered across photos, notes, and social media posts. Travel Diaries brings those memories into one organized platform where users can document journeys, share experiences, and revisit their favorite places through a simple diary-style interface.
- π Travel-themed landing page
- π Community diary feed
- π Clerk-based authentication
- π€ User profile with personal diaries
- β Add new travel diary entries
- βοΈ Update existing diary entries
- ποΈ Delete diary entries
- π¦ Arcjet rate limiting for API protection
- π± Responsive React UI with Material UI
- ποΈ MongoDB-backed persistent storage
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Tier 1: Client / Presentation Layer β
β β
β React Frontend β
β ββ Landing Page β
β ββ Community Diaries β
β ββ Login / Auth Page β
β ββ Add Diary Page β
β ββ Update Diary Page β
β ββ User Profile Page β
βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Tier 2: Application / Business Logic Layer β
β β
β Express Backend β
β ββ REST API routes for users and posts β
β ββ Clerk middleware for authenticated user sync β
β ββ Controllers for diary CRUD operations β
β ββ Arcjet rate limiting for API protection β
β ββ CORS configuration β
β ββ Request validation and response handling β
βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Tier 3: Data / External Services Layer β
β β
β MongoDB + External Services β
β ββ MongoDB database β
β ββ Mongoose models for User and Post β
β ββ Clerk authentication β
β ββ Arcjet security and rate limiting β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
flowchart TD
A[Visitor opens Travel Diaries] --> B[React Frontend]
B --> C{User action}
C -->|Browse diaries| D[GET /posts]
D --> E[Express API]
E --> F[Arcjet read limiter]
F --> G[(MongoDB)]
G --> H[Return community diaries]
H --> B
C -->|Sign in| I[Clerk Authentication]
I --> J[Get Clerk token]
J --> K[POST /user/sync]
K --> L[Create or update MongoDB user]
L --> M[Store userId in localStorage]
C -->|Add diary| N[Protected Add Diary Page]
N --> O[POST /posts]
O --> P[Arcjet write and create limits]
P --> Q[Save Post with user reference]
Q --> G
C -->|Edit diary| R[Update Diary Page]
R --> S[PUT /posts/:id]
S --> T[Arcjet update limit]
T --> U[Update diary document]
U --> G
C -->|Delete diary| V[DELETE /posts/:id]
V --> W[Remove diary document]
W --> G
C -->|View profile| X[GET /user/:id]
X --> Y[Load user with posts]
Y --> G
travel-diaries/
βββ backend/
β βββ package.json
β βββ starting-app/
β βββ travelDiaries/
β βββ app.js
β βββ controllers/
β β βββ post-controller.js
β β βββ user-controllers.js
β βββ lib/
β β βββ arcjet.js
β βββ models/
β β βββ Post.js
β β βββ User.js
β βββ routing/
β β βββ post-routes.js
β β βββ user-routes.js
β βββ package.json
βββ frontend/
β βββ public/
β β βββ screenshorts/
β β βββ travel images and app assets
β βββ src/
β β βββ api-helpers/
β β βββ auth/
β β βββ diaries/
β β βββ header/
β β βββ home/
β β βββ profile/
β β βββ store/
β β βββ App.js
β β βββ index.js
β βββ .env.example
β βββ package.json
βββ README.md
erDiagram
USER {
string _id PK
string clerkId UK
string name
string username
string email UK
string profileImage
string password
objectId[] posts
}
POST {
string _id PK
string title
string description
string image
string location
date date
objectId user FK
}
USER ||--o{ POST : creates
| Collection | Purpose | Key Fields |
|---|---|---|
User |
Stores user identity, Clerk sync data, profile image, and diary references. | clerkId, name, email, profileImage, posts |
Post |
Stores each travel diary entry. | title, description, image, location, date, user |
| Category | Technology |
|---|---|
| Frontend | React, React Router DOM, Redux Toolkit, Material UI |
| Backend | Node.js, Express.js |
| Database | MongoDB, Mongoose |
| Authentication | Clerk |
| Security / Rate Limiting | Arcjet |
| API Client | Axios |
| Tooling | Create React App, Babel, Nodemon |
git clone https://github.com/debarghya131/MERN-Travel-Diaries.git
cd MERN-Travel-Diaries/travel-diariescd backend/travelDiaries
npm installcd ../../frontend
npm installcd ../backend/travelDiaries
npm run devBackend runs on:
http://localhost:5000
cd ../../frontend
npm startFrontend runs on:
http://localhost:3000
Create backend/travelDiaries/.env:
PORT=5000
MONGODB_URL=your_mongodb_connection_string
CORS_ORIGIN=http://localhost:3000
ARCJET_KEY=your_arcjet_key
CLERK_SECRET_KEY=your_clerk_secret_keyCreate frontend/.env:
REACT_APP_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
REACT_APP_API_URL=http://localhost:5000| Variable | Used In | Description |
|---|---|---|
PORT |
Backend | Express server port. |
MONGODB_URL |
Backend | MongoDB connection string. |
CORS_ORIGIN |
Backend | Allowed frontend origin. |
ARCJET_KEY |
Backend | Arcjet API key for rate limiting. |
CLERK_SECRET_KEY |
Backend | Clerk secret key for server-side auth. |
REACT_APP_CLERK_PUBLISHABLE_KEY |
Frontend | Clerk publishable key for React. |
REACT_APP_API_URL |
Frontend | Backend API base URL. |
- Managing authentication between Clerk and the MongoDB user model.
- Keeping the frontend and backend connected through environment-based API URLs.
- Protecting API endpoints from repeated requests and abuse.
- Maintaining user-specific diary ownership for profile and CRUD flows.
- Structuring separate frontend and backend folders in one MERN project.
- Added a
/user/syncAPI to sync Clerk user data into MongoDB. - Used Axios helpers to centralize API calls from the frontend.
- Added Arcjet rate limiters for reads, writes, auth, create, and update actions.
- Created Mongoose
UserandPostmodels with references between users and diaries. - Added CORS origin configuration for safer frontend-backend communication.
Frontend tests can be run with:
cd frontend
npm testManual testing covered:
- Loading community diaries
- Signing in with Clerk
- Syncing authenticated users
- Adding new diary entries
- Updating diary entries
- Deleting diary entries
- Viewing user profile diaries
- Centralized API requests in
frontend/src/api-helpers/helpers.js. - Used MongoDB references to connect users and posts efficiently.
- Added rate limits to reduce unnecessary backend load.
- Kept frontend routes separated by feature for easier maintenance.
- Used environment variables for flexible local and production API URLs.
- Clerk handles authentication and user sessions.
- Backend uses Clerk middleware for request auth support.
- Arcjet protects the API with rate limiting.
- CORS limits which frontend origins can access the backend.
- Sensitive keys are stored in
.envfiles and should not be committed. - Mongoose schemas enforce required fields and field length limits.
- Add direct image upload support instead of image URLs.
- Add likes and comments for community diaries.
- Add search and filters by location, date, or user.
- Add map-based travel diary discovery.
- Add pagination or infinite scroll for large diary feeds.
- Add richer profile customization.
- Learned how to structure a MERN app with separate frontend and backend folders.
- Practiced connecting Clerk authentication with a MongoDB user model.
- Learned how to build REST APIs with Express controllers and routes.
- Improved understanding of Mongoose relationships between users and posts.
- Learned how to add API rate limiting with Arcjet.
- Practiced writing reusable frontend API helpers with Axios.
I always like to make new friends. Follow me on:




