This project is a full-stack blogging platform that includes autosaving with Redis, secure JWT-based authentication, drafts, and support for editing published posts. Built with Vite + React on the frontend and Express.js on the backend.
- β‘ React + Vite frontend with JoditEditor for rich text editing
- π Secure JWT Authentication (stored in HTTP-only cookies)
- πΎ Autosaving using Redis (5s idle or 45s interval)
- π Draft system to resume unfinished posts
- βοΈ Edit already published posts
- π¦ MongoDB for persistent post storage
- π Redis for temporary autosave caching
- π REST API with full CRUD for blog posts
| Layer | Technology |
|---|---|
| Frontend | Vite, React, Axios, JoditEditor |
| Backend | Node.js, Express.js |
| Database | MongoDB |
| Caching | Redis |
| Auth | JWT (via HTTP-only cookies) |
.
βββ frontend/ # React + Vite frontend
β βββ src/
βββ backend/ # Express backend
β βββ index.js
β βββ uploads/
β βββ models/ # MongoDB schemas
β βββ RedisClient.js # Redis client setup
βββ README.md
git clone https://github.com/your-username/blog-platform.git
cd blog-platformcd server
npm installPORT=3000
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_jwt_secret
REDIS_URL=redis://localhost:6379
CLIENT_URL=http://localhost:5173npm run devcd client
npm install
npm run devReact app runs on
http://localhost:5173
- JWT tokens are issued upon login and stored as HTTP-only cookies.
- Tokens are automatically sent with every request using Axios.
axios.post('http://localhost:3000/autoSave', postData, {
withCredentials: true
});- Triggers on:
- 5 seconds of typing inactivity
- Every 45 seconds regardless
- Only active when the post is unsaved (not in draft/published state)
autosave:<userId>redis-cli
keys *
get autosave:123| Method | Endpoint | Description |
|---|---|---|
| POST | /login |
Log in and receive token |
| POST | /register |
Create a new user |
| GET | /me |
Get current user |
| Method | Endpoint | Description |
|---|---|---|
| POST | /posts |
Create post |
| PUT | /posts/:id |
Edit draft/published post |
| GET | /posts/:id |
Fetch single post |
| GET | /posts?status=draft |
Get all draft posts |
| GET | /posts?status=published |
Get all published posts |
| Method | Endpoint | Description |
|---|---|---|
| POST | /autoSave |
Save to Redis |
| GET | /autoSave/:userId |
Load autosaved post |
| DELETE | /autoSave/:userId |
Clear autosaved content |
Make sure Redis is installed and running.
brew install redis
brew services start redissudo apt update
sudo apt install redis
sudo systemctl start redisredis-serverconst cors = require("cors");
app.use(cors({
origin: process.env.CLIENT_URL,
credentials: true
}));{
_id,
userId,
title,
content,
status: "draft" | "published",
createdAt,
updatedAt
}autosave:<userId>Used to store in-progress post content per user.
- User logs in via
/login(JWT token issued in cookie) - Starts a new post or resumes a draft
- Autosave kicks in every 5s idle or 45s interval
- On draft/save:
- MongoDB stores the post
- Redis autosave key is cleared
- User can edit drafts or published posts
- Use Postman to test endpoints
- Use
redis-clito check autosave entries - Add middleware to validate JWT in protected routes
Install:
npm install -D eslint prettier eslint-config-prettier eslint-plugin-reactFor issues or feature requests, contact:
- GitHub Issues: Open a ticket
- Email: your-email@example.com
Let me know if you'd like to add:
- Docker Support
- Vercel/Render deployment
- Screenshots or GIF demo




