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-platform
cd server
npm install
PORT=3000
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_jwt_secret
REDIS_URL=redis://localhost:6379
CLIENT_URL=http://localhost:5173
npm run dev
cd client
npm install
npm run dev
React 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 redis
sudo apt update
sudo apt install redis
sudo systemctl start redis
redis-server
const 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-cli
to check autosave entries - Add middleware to validate JWT in protected routes
Install:
npm install -D eslint prettier eslint-config-prettier eslint-plugin-react
For issues or feature requests, contact:
- GitHub Issues: Open a ticket
- Email: [email protected]
Let me know if you'd like to add:
- Docker Support
- Vercel/Render deployment
- Screenshots or GIF demo