Skip to content

Santoshpatel112/Blog-Application

Repository files navigation

📝 ByteCode Blog Platform

A full-stack, production-ready blog application built with Next.js 16, featuring real-time interactions, rich text editing, and a comprehensive content management system.

Next.js TypeScript Prisma Tailwind CSS

🚀 Features

Core Functionality

  • 📰 Article Management - Create, edit, delete, and publish articles with rich text editor
  • 🔍 Advanced Search - Real-time search across articles with filtering capabilities
  • 💬 Comments System - Engage with readers through nested comments
  • ❤️ Like & Save - Interactive engagement with like/dislike and bookmark features
  • 📊 Analytics Dashboard - Track article performance and user engagement
  • 🎨 Rich Text Editor - Powered by React Quill for professional content creation
  • 🖼️ Image Management - Cloudinary integration for optimized image uploads

User Experience

  • 🔐 Authentication - Secure user authentication via Clerk
  • 🌓 Dark Mode - Seamless theme switching with next-themes
  • 📱 Responsive Design - Mobile-first approach with Tailwind CSS
  • ⚡ Performance - Optimized with Next.js 16 App Router and Server Components
  • ♿ Accessibility - Built with Radix UI primitives for WCAG compliance

🛠️ Tech Stack

Frontend

  • Framework: Next.js 16 (App Router)
  • Language: TypeScript 5
  • Styling: Tailwind CSS 4
  • UI Components: Radix UI, shadcn/ui
  • Rich Text: React Quill
  • Icons: Lucide React

Backend

  • Database: PostgreSQL
  • ORM: Prisma 5.22
  • Authentication: Clerk
  • File Storage: Cloudinary
  • Validation: Zod

DevOps & Tools

  • Package Manager: npm
  • Linting: ESLint 9
  • Type Checking: TypeScript
  • Database Seeding: tsx

📋 Prerequisites

Before you begin, ensure you have the following installed:

  • Node.js 18.x or higher
  • npm or yarn or pnpm
  • PostgreSQL database
  • Git

🔧 Installation

1. Clone the repository

git clone <repository-url>
cd blog

2. Install dependencies

npm install

3. Environment Setup

Create a .env file in the root directory:

# Database
DATABASE_URL="postgresql://user:password@localhost:5432/blog_db"

# Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
CLERK_SECRET_KEY=your_clerk_secret_key
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up

# Cloudinary
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret

4. Database Setup

# Generate Prisma Client
npx prisma generate

# Run migrations
npx prisma migrate dev

# Seed the database (optional)
npm run seed

5. Start Development Server

npm run dev

Visit http://localhost:3000 to see your application.

📁 Project Structure

blog/
├── actions/              # Server actions for data mutations
│   ├── create-article.ts
│   ├── edit-article.ts
│   ├── delete-article.ts
│   ├── like-dislike.ts
│   ├── save-article.ts
│   ├── create-comment.ts
│   └── search.ts
├── app/                  # Next.js App Router
│   ├── (home)/          # Public home pages
│   ├── about/           # About page
│   ├── api/             # API routes
│   ├── article/         # Article detail pages
│   ├── dashboard/       # User dashboard
│   └── layout.tsx       # Root layout
├── components/          # React components
│   ├── articles/        # Article-related components
│   ├── comments/        # Comment components
│   ├── dashboard/       # Dashboard components
│   ├── home/            # Home page components
│   └── ui/              # Reusable UI components
├── hooks/               # Custom React hooks
├── lib/                 # Utility functions
│   ├── prisma.ts        # Prisma client
│   ├── query/           # Database queries
│   └── utils.ts         # Helper functions
├── prisma/              # Database schema and migrations
│   ├── schema.prisma
│   └── seed.ts
└── public/              # Static assets

🎯 Available Scripts

# Development
npm run dev              # Start development server
npm run dev:turbo        # Start with Turbo mode

# Production
npm run build            # Build for production
npm run start            # Start production server

# Database
npm run seed             # Seed database with sample data
npx prisma studio        # Open Prisma Studio
npx prisma migrate dev   # Run migrations

# Code Quality
npm run lint             # Run ESLint

🗄️ Database Schema

Models Overview

User Model

model User {
  id              String          @id @default(uuid())
  clearkUserId    String          @unique
  email           String          @unique
  name            String?
  imageURL        String?
  articles        Article[]
  Comment         Comment[]
  likes           Like[]
  savedArticles   SavedArticle[]
}
  • Stores user profile information
  • Linked to Clerk authentication
  • Manages user-generated content

Article Model

model Article {
  id             String          @id @default(uuid())
  title          String
  content        String
  category       String
  featuredImage  String
  authorId       String
  author         User            @relation(fields: [authorId], references: [id])
  comments       Comment[]
  likes          Like[]
  savedBy        SavedArticle[]
  createAt       DateTime        @default(now())
  updatedAt      DateTime        @updatedAt
}
  • Main content entity
  • Rich text content support
  • Automatic timestamps

Comment Model

model Comment {
  id         String   @id @default(uuid())
  userId     String
  user       User     @relation(fields: [userId], references: [id])
  articleId  String
  article    Article  @relation(fields: [articleId], references: [id])
  body       String
  createdAt  DateTime @default(now())
}
  • User comments on articles
  • Linked to both user and article

Like Model

model Like {
  id         String   @id @default(uuid())
  userId     String
  user       User     @relation(fields: [userId], references: [id])
  articleId  String
  article    Article  @relation(fields: [articleId], references: [id])
  createdAt  DateTime @default(now())
  @@unique([userId, articleId])
}
  • One like per user per article
  • Unique constraint prevents duplicates

SavedArticle Model

model SavedArticle {
  id         String   @id @default(uuid())
  userId     String
  user       User     @relation(fields: [userId], references: [id])
  articleId  String
  article    Article  @relation(fields: [articleId], references: [id])
  createdAt  DateTime @default(now())
  @@unique([userId, articleId])
}
  • Bookmark functionality
  • Unique constraint per user-article pair

Relationships

  • One-to-Many: User → Articles, User → Comments
  • Many-to-Many: Users ↔ Articles (via Likes and SavedArticles)
  • Cascade Deletes: Configured for data integrity

📡 API Reference

Server Actions

Article Actions

Create Article

// actions/create-article.ts
createArticle(formData: FormData)
- Input: title, content, category, featuredImage
- Returns: Created article or error
- Auth: Required

Edit Article

// actions/edit-article.ts
editArticle(articleId: string, formData: FormData)
- Input: articleId, updated fields
- Returns: Updated article or error
- Auth: Required (must be author)

Delete Article

// actions/delete-article.ts
deleteArticle(articleId: string)
- Input: articleId
- Returns: Success or error
- Auth: Required (must be author)

Like/Dislike Article

// actions/like-dislike.ts
toggleLike(articleId: string)
- Input: articleId
- Returns: Updated like status
- Auth: Required

Save Article

// actions/save-article.ts
toggleSave(articleId: string)
- Input: articleId
- Returns: Updated save status
- Auth: Required

Search Articles

// actions/search.ts
searchArticles(query: string)
- Input: search query
- Returns: Matching articles
- Auth: Optional

Comment Actions

Create Comment

// actions/create-comment.ts
createComment(articleId: string, body: string)
- Input: articleId, comment body
- Returns: Created comment
- Auth: Required

Query Functions

Fetch Articles

// lib/query/fetch-articles.ts
- fetchAllArticles(): Get all published articles
- fetchArticleById(id): Get single article with relations
- fetchUserArticles(userId): Get articles by author
- fetchSavedArticles(userId): Get user's saved articles

🎨 Component Library

Article Components

  • ArticleCard - Display article preview
  • ArticleDetailPage - Full article view
  • CreateArticlePage - Article creation form
  • EditArticlePage - Article editing form
  • AllArticlePage - Article listing with filters
  • LikeButton - Interactive like/dislike button
  • ArticleSearchInput - Search functionality

Comment Components

  • CommentsList - Display all comments
  • CommentInput - Add new comment
  • CommentItem - Single comment display

Dashboard Components

  • BlogDashboard - Main

🔐 Authentication Flow

  1. Users sign up/sign in via Clerk
  2. Clerk webhook creates user record in database
  3. User sessions managed by Clerk middleware
  4. Protected routes secured via middleware.ts

🎨 UI Components

Built with shadcn/ui and Radix UI for:

  • Accessible, keyboard-navigable interfaces
  • Consistent design system
  • Dark mode support
  • Responsive layouts

🚀 Deployment

Vercel (Recommended)

# Install Vercel CLI
npm i -g vercel

# Deploy
vercel

Environment Variables

Ensure all environment variables are configured in your deployment platform:

  • Database connection string
  • Clerk API keys
  • Cloudinary credentials

Database Migration

npx prisma migrate deploy

🔄 Workflows

1. Development Workflow

┌─────────────────────────────────────────────────────────────┐
│                    Development Lifecycle                     │
└─────────────────────────────────────────────────────────────┘

1. Setup Environment
   ├── Clone repository
   ├── Install dependencies (npm install)
   ├── Configure .env file
   ├── Setup PostgreSQL database
   └── Run migrations (npx prisma migrate dev)

2. Local Development
   ├── Start dev server (npm run dev)
   ├── Access at http://localhost:3000
   ├── Hot reload enabled
   └── Prisma Studio for DB inspection (npx prisma studio)

3. Feature Development
   ├── Create feature branch (git checkout -b feature/name)
   ├── Implement changes
   ├── Test locally with seeded data
   ├── Check for type errors (TypeScript)
   └── Run linter (npm run lint)

4. Code Review & Merge
   ├── Commit changes (git commit -m "message")
   ├── Push to remote (git push origin feature/name)
   ├── Create Pull Request
   ├── Code review by team
   └── Merge to main branch

5. Deployment
   ├── Auto-deploy on merge (Vercel)
   ├── Run production migrations
   ├── Verify environment variables
   └── Monitor deployment logs

2. Content Creation Workflow

┌─────────────────────────────────────────────────────────────┐
│                   Author Journey                             │
└─────────────────────────────────────────────────────────────┘

Step 1: Authentication
   └── Sign in/Sign up via Clerk
       ├── Email/Password
       ├── Google OAuth
       └── GitHub OAuth

Step 2: Dashboard Access
   └── Navigate to /dashboard
       ├── View recent articles
       ├── Check analytics
       └── Access saved articles

Step 3: Create Article
   └── Click "Create Article"
       ├── Enter title
       ├── Select category
       ├── Upload featured image (Cloudinary)
       └── Write content (Rich Text Editor)
           ├── Format text (bold, italic, headings)
           ├── Add links
           ├── Insert images
           └── Create lists

Step 4: Publish
   └── Submit article
       ├── Validation (Zod schema)
       ├── Save to database (Prisma)
       └── Redirect to article page

Step 5: Manage Content
   └── Article Management
       ├── Edit existing articles
       ├── Delete articles
       ├── View engagement metrics
       └── Respond to comments

3. Reader Engagement Workflow

┌─────────────────────────────────────────────────────────────┐
│                   Reader Journey                             │
└─────────────────────────────────────────────────────────────┘

Step 1: Discovery
   └── Landing Page (/)
       ├── Browse featured articles
       ├── View top articles
       ├── Search by keyword
       └── Filter by category

Step 2: Read Article
   └── Article Detail Page (/article/[id])
       ├── Read full content
       ├── View author info
       ├── Check publish date
       └── See engagement stats

Step 3: Interact
   └── Engagement Options
       ├── Like/Dislike article
       ├── Save for later
       ├── Share article
       └── Leave comment

Step 4: Community
   └── Comments Section
       ├── Read other comments
       ├── Reply to comments
       ├── Engage in discussions
       └── Follow conversations

4. Database Workflow

┌─────────────────────────────────────────────────────────────┐
│                   Data Flow                                  │
└─────────────────────────────────────────────────────────────┘

User Action → Server Action → Prisma ORM → PostgreSQL

Example: Creating an Article
   1. User submits form
      └── /dashboard/article/create

   2. Server Action (create-article.ts)
      ├── Validate input (Zod)
      ├── Check authentication (Clerk)
      └── Process data

   3. Prisma Query
      ├── prisma.article.create()
      ├── Include relations (author)
      └── Return created article

   4. Database Update
      ├── Insert into Article table
      ├── Update foreign keys
      └── Commit transaction

   5. Response
      ├── Revalidate cache
      ├── Redirect to article
      └── Show success toast

5. Authentication Workflow

┌─────────────────────────────────────────────────────────────┐
│                   Auth Flow (Clerk)                          │
└─────────────────────────────────────────────────────────────┘

1. User Access
   └── Visit protected route
       └── middleware.ts checks auth

2. Not Authenticated
   └── Redirect to /sign-in
       ├── Show Clerk sign-in UI
       └── Multiple auth methods

3. Sign In/Sign Up
   └── Clerk handles authentication
       ├── Verify credentials
       ├── Create session
       └── Generate JWT token

4. Webhook (Optional)
   └── Clerk sends user.created event
       └── Create User in database
           ├── Store Clerk user ID
           ├── Save email & profile
           └── Initialize user data

5. Authenticated
   └── Access granted
       ├── Session stored in cookies
       ├── User data available
       └── Protected routes accessible

6. Image Upload Workflow

┌─────────────────────────────────────────────────────────────┐
│                   Cloudinary Integration                     │
└─────────────────────────────────────────────────────────────┘

1. User Selects Image
   └── File input in article form

2. Client-Side Upload
   └── next-cloudinary component
       ├── Validate file type/size
       ├── Show upload progress
       └── Generate preview

3. Cloudinary Processing
   └── Upload to cloud
       ├── Optimize image
       ├── Generate transformations
       ├── Create responsive URLs
       └── Return secure URL

4. Store URL
   └── Save to database
       ├── featuredImage field
       └── Associated with article

5. Display Image
   └── Render on frontend
       ├── Responsive images
       ├── Lazy loading
       └── Optimized delivery

7. Search Workflow

┌─────────────────────────────────────────────────────────────┐
│                   Search Implementation                      │
└─────────────────────────────────────────────────────────────┘

1. User Input
   └── Search bar (header or article page)
       └── Type search query

2. Real-time Search
   └── Debounced input
       ├── Wait for user to stop typing
       └── Trigger search action

3. Server Action (search.ts)
   └── Query database
       ├── Search in title
       ├── Search in content
       ├── Search in category
       └── Filter by relevance

4. Prisma Query
   └── prisma.article.findMany()
       ├── WHERE clause with contains
       ├── Include author data
       └── Order by relevance

5. Display Results
   └── Update UI
       ├── Show matching articles
       ├── Highlight search terms
       ├── Show result count
       └── Handle no results

8. CI/CD Pipeline (Recommended)

┌─────────────────────────────────────────────────────────────┐
│                   Deployment Pipeline                        │
└─────────────────────────────────────────────────────────────┘

1. Code Push
   └── git push origin main

2. Vercel Detection
   └── Webhook triggered
       └── Start build process

3. Build Phase
   ├── Install dependencies
   ├── Run TypeScript compilation
   ├── Run ESLint
   ├── Generate Prisma Client
   └── Build Next.js app (npm run build)

4. Database Migration
   └── npx prisma migrate deploy
       ├── Apply pending migrations
       └── Update production schema

5. Deployment
   ├── Deploy to Vercel edge network
   ├── Set environment variables
   ├── Configure domains
   └── Enable CDN

6. Post-Deployment
   ├── Run health checks
   ├── Monitor error logs
   ├── Verify functionality
   └── Notify team (optional)

🏗️ Architecture Overview

Application Architecture

┌─────────────────────────────────────────────────────────────┐
│                     Client (Browser)                         │
│  ┌────────────┐  ┌────────────┐  ┌────────────┐            │
│  │   Pages    │  │ Components │  │   Hooks    │            │
│  └────────────┘  └────────────┘  └────────────┘            │
└─────────────────────────────────────────────────────────────┘
                          ↕
┌─────────────────────────────────────────────────────────────┐
│                   Next.js App Router                         │
│  ┌────────────┐  ┌────────────┐  ┌────────────┐            │
│  │   Routes   │  │   Server   │  │    API     │            │
│  │            │  │  Actions   │  │   Routes   │            │
│  └────────────┘  └────────────┘  └────────────┘            │
└─────────────────────────────────────────────────────────────┘
                          ↕
┌─────────────────────────────────────────────────────────────┐
│                    Business Logic                            │
│  ┌────────────┐  ┌────────────┐  ┌────────────┐            │
│  │   Prisma   │  │    Zod     │  │   Utils    │            │
│  │    ORM     │  │ Validation │  │            │            │
│  └────────────┘  └────────────┘  └────────────┘            │
└─────────────────────────────────────────────────────────────┘
                          ↕
┌─────────────────────────────────────────────────────────────┐
│                   External Services                          │
│  ┌────────────┐  ┌────────────┐  ┌────────────┐            │
│  │ PostgreSQL │  │   Clerk    │  │ Cloudinary │            │
│  │  Database  │  │    Auth    │  │   Images   │            │
│  └────────────┘  └────────────┘  └────────────┘            │
└─────────────────────────────────────────────────────────────┘

Key Design Patterns

  • Server Components - Default rendering strategy for performance
  • Server Actions - Type-safe mutations without API routes
  • Optimistic Updates - Instant UI feedback before server confirmation
  • Middleware - Route protection and authentication checks
  • Component Composition - Reusable UI components with Radix UI
  • Type Safety - End-to-end TypeScript with Prisma and Zod

🔒 Security Best Practices

Implemented Security Measures

  1. Authentication & Authorization

    • Clerk handles secure authentication
    • JWT tokens for session management
    • Protected routes via middleware
    • User-specific data access controls
  2. Data Validation

    • Zod schemas for input validation
    • Server-side validation on all mutations
    • SQL injection prevention via Prisma
    • XSS protection with React
  3. Environment Variables

    • Sensitive data in .env (not committed)
    • Different configs for dev/prod
    • Secure API key management
  4. Database Security

    • Parameterized queries via Prisma
    • Unique constraints on critical fields
    • Foreign key relationships enforced
    • Connection pooling for performance

🧪 Testing Strategy (Recommended)

Unit Tests

# Install testing dependencies
npm install -D vitest @testing-library/react @testing-library/jest-dom

# Run tests
npm run test

Integration Tests

  • Test server actions with database
  • Mock Clerk authentication
  • Test Prisma queries

E2E Tests

# Install Playwright
npm install -D @playwright/test

# Run E2E tests
npx playwright test

📊 Performance Optimization

Implemented Optimizations

  1. Next.js Features

    • App Router for automatic code splitting
    • Server Components reduce client bundle
    • Image optimization with next/image
    • Font optimization with next/font
  2. Database

    • Prisma connection pooling
    • Indexed fields for fast queries
    • Efficient relations with include/select
  3. Caching

    • Next.js automatic caching
    • Revalidation strategies
    • Static generation where possible
  4. Assets

    • Cloudinary CDN for images
    • Responsive image delivery
    • Lazy loading components

🐛 Troubleshooting

Common Issues

Database Connection Error

# Check DATABASE_URL in .env
# Ensure PostgreSQL is running
# Verify database exists
npx prisma db push

Clerk Authentication Issues

# Verify Clerk keys in .env
# Check middleware.ts configuration
# Ensure public routes are configured

Build Errors

# Clear Next.js cache
rm -rf .next

# Regenerate Prisma Client
npx prisma generate

# Rebuild
npm run build

Module Not Found

# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install

📈 Monitoring & Analytics

Recommended Tools

  • Vercel Analytics - Built-in performance monitoring
  • Sentry - Error tracking and monitoring
  • Prisma Pulse - Real-time database events
  • LogRocket - Session replay and debugging

🔄 Version Control

Git Workflow

# Feature development
git checkout -b feature/new-feature
git add .
git commit -m "feat: add new feature"
git push origin feature/new-feature

# Bug fixes
git checkout -b fix/bug-description
git commit -m "fix: resolve bug description"

# Hotfix
git checkout -b hotfix/critical-issue
git commit -m "hotfix: critical issue fix"

Commit Convention

Follow Conventional Commits:

  • feat: - New feature
  • fix: - Bug fix
  • docs: - Documentation changes
  • style: - Code style changes
  • refactor: - Code refactoring
  • test: - Test additions/changes
  • chore: - Build process or auxiliary tool changes

🤝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository

    # Click "Fork" on GitHub
    git clone https://github.com/your-username/blog.git
  2. Create a feature branch

    git checkout -b feature/amazing-feature
  3. Make your changes

    • Follow code style guidelines
    • Add tests if applicable
    • Update documentation
  4. Commit your changes

    git commit -m 'feat: add amazing feature'
  5. Push to the branch

    git push origin feature/amazing-feature
  6. Open a Pull Request

    • Describe your changes
    • Link related issues
    • Wait for review

Code Style Guidelines

  • Use TypeScript for type safety
  • Follow ESLint rules
  • Use meaningful variable names
  • Add comments for complex logic
  • Keep components small and focused
  • Write reusable utility functions

📝 License

This project is licensed under the MIT License.

🙏 Acknowledgments

📧 Contact

For questions or support, please open an issue on GitHub.


Built with ❤️ using Next.js and modern web technologies

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published