A full-stack blog platform built with the MERN stack (MongoDB, Express.js, React, Node.js) featuring rich content creation, user authentication, and admin approval workflows.
- Features
- Technology Stack
- Architecture
- Prerequisites
- Installation
- Environment Variables
- Running the Application
- Project Structure
- API Endpoints
- Database Schema
- Contributing
- License
- User Authentication: Register and login functionality with JWT tokens
- Rich Content Creation: Create blog posts with multiple content types:
- Text paragraphs
- Subtopics with heading levels
- Images with captions
- YouTube video embeds
- Bullet lists
- Code snippets with syntax highlighting
- Drag-and-Drop Editor: Reorder content sections with intuitive drag-and-drop
- Admin Approval Workflow: Blog posts require admin approval before publication
- Comment System: Readers can comment on blog posts
- Responsive Design: Works on desktop and mobile devices
- Modern UI: Dark theme with animated star background
- Node.js - JavaScript runtime
- Express.js - Web application framework
- MongoDB - NoSQL database
- Mongoose - Object Data Modeling (ODM) library
- JWT - Authentication tokens
- Bcrypt.js - Password hashing
- Cors - Cross-Origin Resource Sharing
- React - Frontend library
- React Router - Routing library
- React Toastify - Notifications
- React Syntax Highlighter - Code snippet highlighting
- React Star Sky - Animated background
- @hello-pangea/dnd - Drag and drop functionality
- Lucide React - Icon library
┌─────────────────┐ HTTP Requests ┌──────────────────┐
│ React Frontend│ ──────────────────→ │ Express Backend │
│ (Port 3000) │ ←────────────────── │ (Port 5000) │
└─────────────────┘ └──────────────────┘
│
▼
┌───────────────┐
│ MongoDB Atlas │
└───────────────┘
The application follows a client-server architecture with a React frontend communicating with a Node.js/Express backend through RESTful APIs. MongoDB serves as the database with Mongoose as the ODM.
- Node.js (v14 or higher)
- MongoDB Atlas account or local MongoDB instance
- Cloudinary account (for image hosting)
- npm or yarn package manager
- Clone the repository:
git clone <repository-url>
cd BLOG_website- Install backend dependencies:
cd backend
npm install- Install frontend dependencies:
cd ../frontend
npm installMONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_jwt_secret_key
PORT=5000REACT_APP_CLOUDINARY_URL=your_cloudinary_upload_url
REACT_APP_BLOG_UPLOAD_PRESET=your_cloudinary_unsigned_presetcd backend
npm start
# or for development with auto-reload
npm run devcd frontend
npm startThe backend will run on http://localhost:5000 and the frontend on http://localhost:3000.
BLOG_website/
├── backend/
│ ├── src/
│ │ ├── config/ # Database configuration
│ │ ├── controllers/ # Request handlers
│ │ ├── middleware/ # Custom middleware
│ │ ├── models/ # Database models
│ │ ├── routes/ # API routes
│ │ └── server.js # Entry point
│ ├── .env # Environment variables
│ └── package.json # Backend dependencies
└── frontend/
├── public/ # Static assets
├── src/
│ ├── Styles/ # CSS stylesheets
│ ├── components/ # React components
│ ├── pages/ # Page components
│ ├── App.js # Main app component
│ └── index.js # Entry point
├── .env # Environment variables
└── package.json # Frontend dependencies
POST /api/auth/register- Register a new userPOST /api/auth/login- Login existing user
GET /api/blogs- Get all approved blogsPOST /api/blogs- Create a new blog (protected)GET /api/blogs/myblogs- Get current user's blogs (protected)GET /api/blogs/admin/pending- Get pending blogs (admin only)PATCH /api/blogs/admin/:id/verify- Approve a blog (admin only)PUT /api/blogs/:id- Edit a blog (protected)GET /api/blogs/:id- Get a specific blog
POST /api/comments/:blogId- Add a comment to a blogGET /api/comments/:blogId- Get comments for a blog
{
username: String,
email: { type: String, unique: true },
password: String,
role: { type: String, default: "user" }
}{
title: { type: String, required: true },
tags: [String],
twoLineDescription: { type: String },
thumbnailUrl: { type: String },
contentSections: [ContentSectionSchema],
author: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
status: { type: String, enum: ["PENDING", "APPROVED"], default: "PENDING" },
createdAt: { type: Date, default: Date.now }
}{
blog: { type: mongoose.Schema.Types.ObjectId, ref: "Blog", required: true },
user: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
username: { type: String, required: true },
content: { type: String, required: true },
parentComment: { type: mongoose.Schema.Types.ObjectId, ref: "Comment", default: null },
createdAt: { type: Date, default: Date.now }
}- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a pull request