Skip to content

Repository files navigation

🌐 WebScope Pro

A production-ready web scraping dashboard built with Next.js 14

Scrape any website β€” including client-side rendered apps β€” and instantly view titles, headings, meta descriptions, and visible body text. All results are stored, searchable, and displayed in a beautiful authenticated dashboard.

Next.js TypeScript Prisma Tailwind CSS Puppeteer


✨ Features

  • πŸ”’ Authentication β€” Email/password auth with NextAuth.js (credentials + JWT)
  • πŸ€– Puppeteer Scraping β€” Headless Chromium renders JavaScript before extracting data β€” works on SPAs, React, and Next.js sites
  • πŸ“Š Dashboard β€” Stats cards, paginated logs table, detail modals, real-time feed
  • πŸ—„οΈ Persistent Storage β€” All scrape results saved to Neon PostgreSQL via Prisma ORM
  • ⚑ Real-time Updates β€” Socket.IO broadcasts new scrape logs instantly
  • πŸŒ™ Dark Mode β€” Toggle between light and dark themes
  • πŸ›‘οΈ Validation β€” Zod schemas for URL, registration, and login inputs
  • πŸ“± Responsive β€” Mobile-first UI with Tailwind CSS

🧱 Tech Stack

Layer Technology
Framework Next.js 14 (App Router)
Language TypeScript 5
Styling Tailwind CSS 3
Auth NextAuth.js v4 (Credentials + JWT)
Scraping Puppeteer (headless Chromium)
Database PostgreSQL (Neon)
ORM Prisma 7
Validation Zod 4
Real-time Socket.IO 4
Password Hashing bcrypt.js

πŸ“ Project Structure

webscope/
β”œβ”€β”€ prisma/
β”‚   └── schema.prisma          # Database models (User, RequestLog, ScrapedData)
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ [...nextauth]/route.ts   # NextAuth handler
β”‚   β”‚   β”‚   β”‚   └── register/route.ts        # POST /api/auth/register
β”‚   β”‚   β”‚   β”œβ”€β”€ logs/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ [id]/route.ts            # DELETE /api/logs/:id
β”‚   β”‚   β”‚   β”‚   └── route.ts                 # GET  /api/logs
β”‚   β”‚   β”‚   β”œβ”€β”€ scrape/route.ts              # POST /api/scrape
β”‚   β”‚   β”‚   └── stats/route.ts               # GET  /api/stats
β”‚   β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   β”‚   β”œβ”€β”€ login/page.tsx               # Login page
β”‚   β”‚   β”‚   └── register/page.tsx            # Register page
β”‚   β”‚   β”œβ”€β”€ dashboard/page.tsx               # Protected dashboard
β”‚   β”‚   β”œβ”€β”€ layout.tsx                       # Root layout + SessionProvider
β”‚   β”‚   β”œβ”€β”€ page.tsx                         # Landing page
β”‚   β”‚   └── globals.css                      # Global styles + animations
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ Button.tsx           # Reusable button (variants, loading)
β”‚   β”‚   β”œβ”€β”€ Card.tsx             # Glass-effect card wrapper
β”‚   β”‚   β”œβ”€β”€ DetailModal.tsx      # Scrape result detail modal
β”‚   β”‚   β”œβ”€β”€ EmptyState.tsx       # Empty state illustration
β”‚   β”‚   β”œβ”€β”€ LoadingSpinner.tsx   # Spinner component
β”‚   β”‚   β”œβ”€β”€ LogsTable.tsx        # Paginated logs table
β”‚   β”‚   β”œβ”€β”€ Navbar.tsx           # Sticky nav with auth + theme toggle
β”‚   β”‚   β”œβ”€β”€ Pagination.tsx       # Page navigation controls
β”‚   β”‚   β”œβ”€β”€ RequestHistory.tsx   # Request history list
β”‚   β”‚   β”œβ”€β”€ ResponseTimeBadge.tsx# Color-coded response time badge
β”‚   β”‚   β”œβ”€β”€ ScrapeResultCard.tsx # Quick result preview card
β”‚   β”‚   β”œβ”€β”€ SessionProvider.tsx  # NextAuth session wrapper
β”‚   β”‚   β”œβ”€β”€ SkeletonLoader.tsx   # Loading skeleton
β”‚   β”‚   β”œβ”€β”€ StatsCards.tsx       # Stats overview (3-column grid)
β”‚   β”‚   β”œβ”€β”€ StatusBadge.tsx      # HTTP status code badge
β”‚   β”‚   └── ThemeToggle.tsx      # Dark/light mode toggle
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”œβ”€β”€ auth.ts              # NextAuth config (credentials provider)
β”‚   β”‚   β”œβ”€β”€ prisma.ts            # Prisma client singleton
β”‚   β”‚   β”œβ”€β”€ socket.ts            # Socket.IO server init
β”‚   β”‚   └── validators.ts        # Zod schemas (URL, register, login)
β”‚   β”œβ”€β”€ pages/api/
β”‚   β”‚   └── socketio.ts          # Socket.IO handshake endpoint
β”‚   β”œβ”€β”€ types/
β”‚   β”‚   β”œβ”€β”€ index.ts             # Shared TypeScript interfaces
β”‚   β”‚   └── next-auth.d.ts       # NextAuth type augmentation
β”‚   └── middleware.ts            # Protects /dashboard routes
β”œβ”€β”€ .env                         # Environment variables
β”œβ”€β”€ package.json
β”œβ”€β”€ tailwind.config.ts
β”œβ”€β”€ tsconfig.json
└── next.config.mjs

πŸ—ƒοΈ Database Schema

model User {
  id        String       @id @default(uuid())
  name      String?
  email     String       @unique
  password  String
  logs      RequestLog[]
  createdAt DateTime     @default(now())
}

model RequestLog {
  id           String        @id @default(uuid())
  url          String
  method       String
  statusCode   Int
  responseTime Int
  userId       String
  user         User          @relation(fields: [userId], references: [id])
  scrapedData  ScrapedData[]
  createdAt    DateTime      @default(now())
}

model ScrapedData {
  id        String     @id @default(uuid())
  requestId String
  request   RequestLog @relation(fields: [requestId], references: [id], onDelete: Cascade)
  title     String
  headings  String[]
  meta      String?
  bodyText  String?
  createdAt DateTime   @default(now())
}

πŸ”Œ API Routes

Method Endpoint Auth Description
POST /api/auth/register No Create new user account
POST /api/auth/[...nextauth] No NextAuth sign-in / sign-out
POST /api/scrape Yes Scrape a URL with Puppeteer
GET /api/logs?page=1&pageSize=10 Yes Paginated scrape history
DELETE /api/logs/:id Yes Delete a log (ownership verified)
GET /api/stats Yes Dashboard stats (total, avg time, success %)

πŸš€ Getting Started

Prerequisites

  • Node.js 18+
  • PostgreSQL database (or a Neon free tier)

1. Clone the repo

git clone https://github.com/Tushardevx01/webscope.git
cd webscope

2. Install dependencies

npm install

3. Configure environment variables

Create a .env file in the project root:

# PostgreSQL connection string (Neon or local)
DATABASE_URL="postgresql://user:password@host:5432/dbname?sslmode=require"

# NextAuth
NEXTAUTH_SECRET="your-random-secret-here"
NEXTAUTH_URL="http://localhost:3000"

# Gemini API (server-side only)
GEMINI_API_KEY="your_key_here"

Generate a secret: openssl rand -base64 32

4. Push database schema

npx prisma db push

5. Start the dev server

npm run dev

Open http://localhost:3000 β€” register an account and start scraping.


πŸ—οΈ Build for Production

npm run build   # Runs prisma generate + next build
npm start       # Starts production server

πŸ“‘ How Scraping Works

  1. User submits a URL from the dashboard
  2. Server validates the URL with Zod
  3. Puppeteer launches headless Chromium
  4. Navigates to the page, waits for networkidle2 (JavaScript fully rendered)
  5. Extracts from the live DOM:
    • document.title
    • All <h1> and <h2> elements
    • <meta name="description"> content
    • document.body.innerText (truncated to 5000 chars)
  6. Records HTTP status code and response time
  7. Saves everything to PostgreSQL via Prisma
  8. Broadcasts the new log via Socket.IO
  9. Returns structured JSON to the frontend

Why Puppeteer? Traditional HTTP scrapers (Axios + Cheerio) only see the raw HTML. Modern sites built with React, Next.js, or Vue render content via JavaScript β€” Puppeteer runs a real browser to capture the fully-rendered page.


🎨 UI Design

  • Gradient backgrounds β€” gray-50 β†’ blue-50 (light) / gray-950 β†’ indigo-950 (dark)
  • Glass-effect cards β€” bg-white/70 backdrop-blur-xl with soft borders
  • Indigo primary accent with emerald success and rose error badges
  • Smooth transitions β€” fade-in animations, hover scale effects
  • Skeleton loaders during data fetching
  • Empty state illustration when no scrapes exist
  • Fully responsive β€” works on mobile, tablet, and desktop

πŸ›‘οΈ Security

  • Passwords hashed with bcrypt (12 salt rounds)
  • JWT-based sessions via NextAuth
  • Middleware protects /dashboard routes
  • API routes verify session before any DB operation
  • Log deletion checks ownership (userId)
  • Rate limiting on scrape endpoint (1 request per 3 seconds per user)
  • Input validation with Zod on all endpoints
  • Puppeteer runs with --no-sandbox --disable-dev-shm-usage for containerized environments

πŸ“ Environment Variables

Variable Required Description
DATABASE_URL Yes PostgreSQL connection string
NEXTAUTH_SECRET Yes Random string for JWT signing
NEXTAUTH_URL Yes Base URL of the app (http://localhost:3000)
GEMINI_API_KEY No* Google Gemini API key for Website Animal Spirit generation (used server-side only)

* If omitted, WebScope uses deterministic fallback animal spirits instead of AI-generated output.


🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is open source and available under the MIT License.


Built with ❀️ by Tushar

Releases

Packages

Contributors

Languages