A full-featured blogging and reading platform built with the MERN stack, enabling users to create, share, and engage with blog posts in a modern, responsive interface.
- Project Overview
- Features
- Tech Stack
- Project Architecture & Workflow
- ER Diagram
- Folder Structure
- Setup & Installation
- Environment Variables
- Backend Description
- Frontend Description
- Database Management
- Test Credentials
- Team Members & Responsibilities
- Future Scope
- License
LinkRead is a comprehensive blogging platform designed to solve the problem of fragmented content sharing and engagement. It provides a centralized space where users can:
- Create and publish rich-text blog posts with images, code snippets, and formatted content
- Read and discover quality content from other users through an intuitive home feed
- Engage with content through upvotes, downvotes, and threaded comments
- Manage their profile with personalized user pages showing all published posts
Built using the MERN stack (MongoDB, Express.js, React.js, Node.js), LinkRead combines modern web technologies to deliver a fast, scalable, and user-friendly blogging experience.
-
User Authentication
- Secure registration and login system with JWT-based authentication
- Password encryption using bcrypt
- Protected routes for authenticated users only
- Persistent login sessions
-
Blog Post Management
- Create blog posts with rich text editor (Quill)
- Edit and delete your own posts
- Add images, code snippets, tips, and learnings to posts
- Tag-based categorization
- Draft saving functionality
-
Content Discovery
- Home page with all published posts
- Search functionality across titles, content, and tags
- View individual posts with full content display
- Upvote/downvote system for posts
- Verification scoring system
-
User Profiles
- Personalized profile pages
- Display user information (name, email, bio, profile picture)
- Show total post count
- List all posts by the user
- Edit profile information
-
Engagement Features
- Threaded comment system on posts
- Upvote/downvote on comments
- Report inappropriate content (posts and comments)
- User streak tracking for consistent engagement
-
Community Features
- Thread/community creation and management
- Moderator roles and permissions
- Community rules and moderation logs
- Direct messaging between users
- React.js (v19.1.1) - UI library for building interactive interfaces
- React Router DOM (v7.9.4) - Client-side routing and navigation
- Vite (v7.1.7) - Fast build tool and development server
- Axios (v1.13.1) - HTTP client for API requests
- React Quill - Rich text editor for blog content
- React Icons - Icon library for UI elements
- CSS - Custom styling with modern CSS features
- Node.js - JavaScript runtime environment
- Express.js (v5.1.0) - Web application framework
- MongoDB - NoSQL database for data storage
- Mongoose (v8.7.1) - MongoDB object modeling (ODM)
- JWT (jsonwebtoken v9.0.2) - Token-based authentication
- bcryptjs (v3.0.2) - Password hashing and encryption
- CORS - Cross-origin resource sharing middleware
- Multer - File upload handling
- Validator - Data validation library
- dotenv - Environment variable management
- Slugify - URL-friendly string generation
- Google Generative AI - AI integration capabilities
- ESLint - Code linting and quality checks
- Git - Version control
LinkRead follows a classic three-tier MERN architecture:
-
Client Layer (React Frontend)
- Handles user interface and interactions
- Manages application state and routing
- Sends HTTP requests to the backend API
-
Server Layer (Express Backend)
- Processes API requests from the frontend
- Implements business logic and validation
- Manages authentication and authorization
- Interacts with the database
-
Database Layer (MongoDB)
- Stores all application data (users, posts, comments, etc.)
- Handles data persistence and retrieval
- Manages relationships between entities
- User fills out registration/login form in React frontend
- Frontend sends POST request to
/api/auth/registeror/api/auth/login - Backend validates input data using validator library
- For registration: Password is hashed with bcrypt, user document is created in MongoDB
- For login: Password is compared with stored hash
- Backend generates JWT token and sends it back to frontend
- Frontend stores token in localStorage
- Token is included in subsequent requests via Authorization header
- Authenticated user writes post content using Quill editor
- Frontend sends POST request to
/api/postswith post data and JWT token - Backend auth middleware verifies JWT token
- Backend validates post data (title, content, etc.)
- New Post document is created in MongoDB with author reference to User
- Backend returns created post data to frontend
- Frontend redirects user to the new post page or home page
- User navigates to home page
- Frontend sends GET request to
/api/posts - Backend queries MongoDB for all published posts (isDraft: false)
- Posts are populated with author information
- Backend returns array of post objects
- Frontend renders posts in a grid/list layout
- User can click on a post to view full details
- User clicks upvote button on a post
- Frontend sends PUT request to
/api/posts/:id/upvotewith JWT token - Backend verifies authentication
- Backend checks if user already upvoted/downvoted
- User ID is added to/removed from upvotes array in Post document
- Updated post is returned to frontend
- Frontend updates UI to reflect new upvote count
The following Entity-Relationship diagram illustrates the database schema and relationships between collections:
erDiagram
USER ||--o{ POST : "creates"
USER ||--o{ COMMENT : "writes"
USER ||--o{ REPORT : "submits"
USER ||--o{ THREAD : "creates"
USER ||--o{ MESSAGE : "sends"
USER ||--o{ MESSAGE : "receives"
POST ||--o{ COMMENT : "has"
POST }o--o{ USER : "upvoted_by"
POST }o--o{ USER : "downvoted_by"
COMMENT }o--o{ USER : "upvoted_by"
COMMENT ||--o{ COMMENT : "parent_of"
THREAD ||--o{ USER : "has_moderators"
THREAD ||--o{ USER : "has_members"
USER {
ObjectId _id PK
String username
String email UK
String password
String googleId
String profilePic
String bio
Object streak
Number currentStreak
Date lastActiveDate
Date createdAt
Date updatedAt
}
POST {
ObjectId _id PK
String title
String content
ObjectId author FK
String tips
String learnings
String codeSnippet
String image
ObjectId[] upvotes FK
ObjectId[] downvotes FK
Boolean isVerified
Number verificationScore
String[] tags
Boolean isDraft
Date lastSavedAt
Date createdAt
Date updatedAt
}
COMMENT {
ObjectId _id PK
String content
ObjectId post FK
ObjectId author FK
ObjectId[] upvotes FK
ObjectId parentComment FK
Date createdAt
Date updatedAt
}
THREAD {
ObjectId _id PK
String name UK
String slug UK
String description
Object[] rules
String[] tags
String category
String visibility
String iconUrl
String bannerUrl
String color
ObjectId creator FK
ObjectId[] moderators FK
ObjectId[] members FK
String membershipPolicy
ObjectId[] pinnedPosts FK
Object[] joinRequests
Object stats
Object settings
Object automod
Object[] moderationLog
Boolean isArchived
Date archivedAt
Date createdAt
Date updatedAt
}
REPORT {
ObjectId _id PK
ObjectId reporter FK
ObjectId targetId
String targetModel
String reason
String status
Date createdAt
Date updatedAt
}
MESSAGE {
ObjectId _id PK
ObjectId sender FK
ObjectId receiver FK
String subject
String body
Object[] attachments
String threadKey
Boolean seen
Date seenAt
String status
Date createdAt
Date updatedAt
}
- USER to POST: One-to-Many - A user can create multiple posts, but each post has one author
- USER to COMMENT: One-to-Many - A user can write multiple comments
- POST to COMMENT: One-to-Many - A post can have multiple comments
- COMMENT to COMMENT: Self-referencing - Comments can be replies to other comments (threaded)
- POST/COMMENT to USER (upvotes/downvotes): Many-to-Many - Multiple users can upvote/downvote posts and comments
- USER to THREAD: One-to-Many - A user can create multiple threads/communities
- THREAD to USER (moderators/members): Many-to-Many - Threads have multiple moderators and members
- USER to MESSAGE: One-to-Many - Users can send and receive multiple messages
- USER to REPORT: One-to-Many - Users can submit multiple reports
LinkRead/
├── backend/
│ ├── config/
│ │ └── db.js # MongoDB connection configuration
│ ├── controllers/
│ │ ├── authController.js # Authentication logic (login, register)
│ │ ├── postController.js # Post CRUD operations
│ │ ├── commentController.js # Comment operations
│ │ ├── userController.js # User profile management
│ │ ├── reportController.js # Content reporting
│ │ ├── threadController.js # Community/thread management
│ │ ├── messageController.js # Direct messaging
│ │ └── aiController.js # AI integration features
│ ├── middleware/
│ │ ├── auth.js # JWT authentication middleware
│ │ ├── errorHandler.js # Global error handling
│ │ └── upload.js # File upload middleware (Multer)
│ ├── models/
│ │ ├── User.js # User schema
│ │ ├── Post.js # Post schema
│ │ ├── Comment.js # Comment schema
│ │ ├── Thread.js # Thread/community schema
│ │ ├── Report.js # Report schema
│ │ └── Message.js # Message schema
│ ├── routes/
│ │ ├── authRoutes.js # Authentication endpoints
│ │ ├── postRoutes.js # Post endpoints
│ │ ├── commentRoutes.js # Comment endpoints
│ │ ├── userRoutes.js # User endpoints
│ │ ├── reportRoutes.js # Report endpoints
│ │ ├── threadRoutes.js # Thread endpoints
│ │ ├── messageRoutes.js # Message endpoints
│ │ └── aiRoutes.js # AI endpoints
│ ├── utils/
│ │ ├── seedMockData.js # Database seeding utility
│ │ ├── cleanupPosts.js # Data cleanup utility
│ │ └── aiService.js # AI service integration
│ ├── .env # Environment variables (not in git)
│ ├── server.js # Express server entry point
│ └── package.json # Backend dependencies
│
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ │ └── Navbar.jsx # Navigation bar component
│ │ ├── pages/
│ │ │ ├── Home.jsx # Home page with post feed
│ │ │ ├── LogIn.jsx # Login page
│ │ │ ├── Register.jsx # Registration page
│ │ │ ├── CreatePost.jsx # Create/edit post page
│ │ │ ├── PostDetails.jsx # Individual post view
│ │ │ └── Profile.jsx # User profile page
│ │ ├── styles/
│ │ │ ├── Home.css # Home page styles
│ │ │ ├── Login.css # Login page styles
│ │ │ ├── Register.css # Register page styles
│ │ │ ├── CreatePost.css # Create post page styles
│ │ │ ├── PostDetails.css # Post details page styles
│ │ │ ├── Profile.css # Profile page styles
│ │ │ └── Navbar.css # Navbar styles
│ │ ├── App.jsx # Main app component with routing
│ │ ├── main.jsx # React entry point
│ │ ├── index.css # Global styles
│ │ └── api.js # API configuration
│ ├── public/ # Static assets
│ ├── package.json # Frontend dependencies
│ └── vite.config.js # Vite configuration
│
├── .gitignore
├── LICENSE
└── README.md # This file
- backend/config: Database connection and configuration files
- backend/controllers: Business logic for handling requests
- backend/middleware: Reusable middleware functions (auth, error handling, file uploads)
- backend/models: Mongoose schemas defining data structure
- backend/routes: API endpoint definitions
- backend/utils: Utility functions and helper scripts
- frontend/src/components: Reusable React components
- frontend/src/pages: Page-level components for different routes
- frontend/src/styles: CSS files for styling components and pages
Follow these detailed steps to set up and run LinkRead on your local machine.
Before you begin, ensure you have the following installed:
-
Node.js (v16 or higher) and npm (v8 or higher)
- Download from nodejs.org
- Verify installation:
node --versionandnpm --version
-
MongoDB connection string
- Option 1: Use MongoDB Atlas (free cloud database)
- Option 2: Install MongoDB locally from mongodb.com
-
Git for cloning the repository
- Download from git-scm.com
# Clone the repository
git clone https://github.com/yourusername/LinkRead.git
# Navigate to the project directory
cd LinkRead-
Navigate to the backend folder:
cd backend -
Install backend dependencies:
npm install
-
Create a
.envfile in thebackenddirectory:touch .env
-
Add environment variables to the
.envfile (see Environment Variables section below for details):PORT=8001 MONGODB_URI=your_mongodb_connection_string_here JWT_SECRET=your_jwt_secret_here CLIENT_URL=http://localhost:5173
-
Start the backend server:
# Development mode npm run dev # OR production mode npm start
You should see:
Server running on port 8001andMongoDB Connected
-
Open a new terminal and navigate to the frontend folder:
cd frontend -
Install frontend dependencies:
npm install
-
(Optional) Configure API base URL:
- The API base URL is configured in
src/api.js - Default is
http://localhost:8001/api - Modify if your backend runs on a different port
- The API base URL is configured in
-
Start the frontend development server:
npm run dev
You should see:
Local: http://localhost:5173/
-
Ensure both servers are running:
- Backend:
http://localhost:8001 - Frontend:
http://localhost:5173
- Backend:
-
Open your browser and navigate to:
http://localhost:5173 -
You can now:
- Register a new account
- Log in with existing credentials (see Test Credentials)
- Create and publish blog posts
- Browse posts on the home page
- View user profiles
- The backend must be running before the frontend can fetch data
- Make sure the ports (8001 for backend, 5173 for frontend) are not in use by other applications
- CORS is configured to allow requests from
http://localhost:*origins - If you change the backend port, update the API URL in
frontend/src/api.js
Create a .env file in the backend directory with the following variables:
PORT=8001
MONGODB_URI=your_mongodb_connection_string_here
JWT_SECRET=your_jwt_secret_here
CLIENT_URL=http://localhost:5173-
PORT (default: 8001)
- The port number on which the Express server will run
- Can be changed to any available port (e.g., 3000, 5000, 8000)
-
MONGODB_URI (required)
- Your MongoDB connection string
- For MongoDB Atlas:
mongodb+srv://<username>:<password>@cluster.mongodb.net/linkread?retryWrites=true&w=majority - For local MongoDB:
mongodb://localhost:27017/linkread - Replace
<username>and<password>with your MongoDB credentials - The database name (
linkread) can be customized
-
JWT_SECRET (required)
- A secret key used to sign and verify JWT tokens
- Should be a long, random string for security
- Example:
your_super_secret_jwt_key_change_this_in_production - Important: Never commit this to version control; keep it secure
-
CLIENT_URL (default: http://localhost:5173)
- The URL of your frontend application
- Used for CORS configuration
- Change to your production frontend URL when deploying
If you need to configure the API URL differently, create a .env file in the frontend directory:
VITE_API_URL=http://localhost:8001/api- VITE_API_URL (optional)
- The base URL for backend API requests
- Currently hardcoded in
src/api.jsbut can be made configurable - Must start with
VITE_prefix to be accessible in Vite applications
The backend is built with Express.js, a minimal and flexible Node.js web application framework. It follows the MVC (Model-View-Controller) pattern with a RESTful API architecture:
- Models: Define data schemas using Mongoose ODM
- Controllers: Handle business logic and request processing
- Routes: Define API endpoints and map them to controllers
-
JWT (JSON Web Tokens): Stateless authentication mechanism
- Tokens are generated upon login and stored in client localStorage
- Protected routes verify tokens via
authmiddleware - Tokens include user ID and expiration time
-
bcryptjs: Password hashing and comparison
- Passwords are hashed with salt rounds before storage
- Never stores plain-text passwords
- Secure password verification during login
-
User Management (
userController.js)- Get user profile information
- Update user profile (username, bio, profile picture)
- Track user statistics (post count, streak)
-
Post Management (
postController.js)- Create new posts with rich content
- Update existing posts (author-only)
- Delete posts (author-only)
- Get all posts with pagination and filtering
- Search posts by title, content, or tags
- Upvote/downvote functionality
- Draft saving and publishing
-
Comment System (
commentController.js)- Create comments on posts
- Threaded/nested comments (replies)
- Upvote comments
- Delete comments (author or post owner)
-
Reporting System (
reportController.js)- Report inappropriate posts or comments
- Track report status (Pending, Reviewed, Resolved)
- Admin moderation capabilities
-
Community Features (
threadController.js)- Create and manage threads/communities
- Moderator permissions
- Member management
- Community rules and settings
-
Messaging (
messageController.js)- Direct messaging between users
- Message threads
- Read receipts
- Auth:
/api/auth/register,/api/auth/login - Posts:
/api/posts(GET, POST),/api/posts/:id(GET, PUT, DELETE) - Comments:
/api/comments(POST),/api/comments/:id(DELETE) - Users:
/api/users/profile,/api/users/:id - Reports:
/api/reports(POST, GET)
- Global Error Handler: Centralized error handling middleware (
errorHandler.js) - Validation Errors: Mongoose validation errors are caught and formatted
- Authentication Errors: 401 Unauthorized for invalid/missing tokens
- Authorization Errors: 403 Forbidden for insufficient permissions
- Not Found Errors: 404 for non-existent resources
- Server Errors: 500 for unexpected server issues
All errors return consistent JSON responses:
{
"success": false,
"message": "Error description",
"error": "Detailed error info (in development)"
}The frontend is built with React.js using Vite as the build tool for fast development and optimized production builds. It follows a component-based architecture with:
- Functional Components: Modern React with hooks
- React Router: Client-side routing for single-page application experience
- Axios: HTTP client for API communication
- Context/State Management: Component-level state with hooks
The application uses React Router DOM for navigation:
Routes:
- / → Home (public)
- /login → Login (public)
- /register → Register (public)
- /create-post → CreatePost (protected)
- /edit-post/:id → CreatePost (protected)
- /post/:id → PostDetails (public)
- /profile/:userId → Profile (public)Protected routes check for authentication token and redirect to login if not authenticated.
-
Home (
Home.jsx)- Displays all published blog posts in a grid layout
- Search functionality to filter posts
- Post cards show title, excerpt, author, and engagement metrics
- Click on a post to view full details
-
Login/Register (
LogIn.jsx,Register.jsx)- Clean, centered glass-morphism UI design
- Form validation and error handling
- Automatic redirect to home upon successful authentication
- Stores JWT token in localStorage
-
Create/Edit Post (
CreatePost.jsx)- Rich text editor (React Quill) for content creation
- Fields for title, content, tips, learnings, code snippets
- Tag input for categorization
- Image upload support
- Draft saving functionality
- Edit mode pre-fills existing post data
-
Post Details (
PostDetails.jsx)- Full post content with HTML rendering
- Author information and post metadata
- Upvote/downvote buttons
- Delete button (visible only to post author)
- Comment section (if implemented)
-
Profile (
Profile.jsx)- User information display (name, email, bio, profile picture)
- Total post count
- Grid of all posts by the user
- Edit profile functionality (for own profile)
- Responsive Design: Works seamlessly on desktop, tablet, and mobile devices
- Modern Aesthetics: Glass-morphism effects, smooth animations, vibrant gradients
- Dark Theme: Consistent dark color scheme throughout the application
- Loading States: Visual feedback during API requests
- Error Handling: User-friendly error messages
- Active Route Highlighting: Navbar shows current page
The frontend communicates with the backend via Axios:
// API base configuration (src/api.js)
const API_URL = 'http://localhost:8001/api';
// Example request with authentication
axios.get(`${API_URL}/posts`, {
headers: {
Authorization: `Bearer ${token}`
}
});All authenticated requests include the JWT token in the Authorization header.
LinkRead uses MongoDB, a NoSQL document database, with Mongoose as the Object Data Modeling (ODM) library.
The database consists of six main collections:
- users - User accounts and profiles
- posts - Blog posts and articles
- comments - Comments on posts (with threading support)
- threads - Communities/discussion threads
- reports - Content moderation reports
- messages - Direct messages between users
MongoDB doesn't enforce relationships like SQL databases, but Mongoose provides reference-based relationships:
- References (ObjectId): Posts reference Users via
authorfield - Population: Mongoose
.populate()method fetches referenced documents - Arrays of References: Posts have arrays of User IDs for upvotes/downvotes
- Embedded Documents: Threads have embedded subdocuments for rules and moderation logs
Performance-optimized indexes are created for:
- User email: Unique index for fast login lookups
- Post search: Text index on title, content, and tags for full-text search
- Thread slug: Unique index for URL-friendly thread names
- Message threadKey: Index for efficient message thread queries
- User email: Must be unique across all users
- Thread name: Must be unique across all threads
- Thread slug: Must be unique for URL routing
Mongoose schemas enforce data validation:
- Required fields: username, email, password (User); title, content, author (Post)
- Type validation: String, Number, Boolean, Date, ObjectId
- String constraints: minlength, maxlength, trim, lowercase
- Enum validation: Specific allowed values (e.g., report status, visibility)
- Custom validation: Email format, password strength (via validator library)
The utils/seedMockData.js script can populate the database with sample data for development and testing purposes.
For quick testing and evaluation, you can use the following pre-configured account:
- Email:
test29@gmail.com - Password:
290805
This test account has existing posts and profile data for demonstration purposes.
LinkRead was developed by a team of four dedicated members, each contributing their expertise to different aspects of the project:
- Overall project coordination and documentation
- Frontend development for core pages (Home, PostDetails, CreatePost, Profile)
- UI/UX design decisions and component structure
- Integration between frontend and backend APIs
- README and project presentation structure
- Testing and quality assurance
- Backend development (Express routes and controllers)
- User authentication and authorization logic
- Post CRUD APIs (create, read, update, delete posts)
- Middleware implementation (auth middleware, error handling)
- Environment configuration and server setup
- API endpoint design and implementation
- Database design and schema modeling (MongoDB/Mongoose)
- Entity-Relationship mapping and model relationships
- Query optimization and data validation
- Implementation of comments, likes, and engagement features
- Database indexing and performance tuning
- Support in backend testing and debugging
- Frontend state management and API integration
- Navbar component and authentication pages (Login/Register)
- Routing flows and protected route implementation
- Profile page data binding (user details and post counts)
- Testing frontend flows and fixing UI bugs
- Assistance in deployment steps and documentation
LinkRead has significant potential for expansion and enhancement. Planned future improvements include:
- Advanced Search & Filters: Filter posts by date, popularity, tags, author
- Pagination: Implement infinite scroll or page-based navigation for better performance
- Rich Media Support: Video embeds, audio files, image galleries
- Social Features: Follow users, personalized feed, notifications
- Bookmarks/Favorites: Save posts for later reading
- Post Analytics: View counts, engagement metrics, trending posts
- Email Notifications: New comments, mentions, weekly digest
- Mobile App: React Native version for iOS and Android
- Real-time Updates: WebSocket integration for live comments and notifications
- Image Optimization: Cloudinary or S3 integration for image hosting
- Caching: Redis for session management and frequently accessed data
- Testing: Unit tests (Jest), integration tests, E2E tests (Cypress)
- CI/CD Pipeline: Automated testing and deployment
- Performance Monitoring: Error tracking (Sentry), analytics (Google Analytics)
- SEO Optimization: Server-side rendering, meta tags, sitemaps
- Enhanced Moderation Tools: Automated spam detection, content filtering
- User Reputation System: Karma points, badges, achievements
- Thread/Community Features: Fully implement thread functionality
- Admin Dashboard: Comprehensive admin panel for platform management
This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ by the LinkRead Team
For questions or support, please open an issue on GitHub or contact the development team.