UpLink is a full-stack MERN job board platform built with Next.js 16 (App Router) . It connects job seekers with employers through a clean, modern interface that is fully server-rendered for SEO β meaning job listings and company profiles are indexed by Google.
The platform supports three distinct user roles, each with a dedicated dashboard:
π€ Job Seeker
π’ Employer
π‘οΈ Admin
Browse & apply for jobs
Post & manage job listings
Platform-wide oversight
Build a resume in-app
Track applicants per listing
Approve company registrations
Set up smart job alerts
Update applicant statuses
Manage users, jobs & categories
Bookmark jobs for later
View hiring analytics
Moderate company reviews
The project leverages Next.js App Router capabilities β SSR/SSG for SEO, API route handlers (no separate backend), edge middleware for auth, generateMetadata for dynamic meta tags, and next/image for optimized image delivery.
Browse all jobs with search, filter (category, type, location, salary, remote), and sort
View SEO-optimized job detail pages (server-rendered)
Apply with in-app or uploaded resume + cover letter
Resume Builder β multi-step form with live preview β generates downloadable PDF
Track all applications with real-time status updates
Bookmark/save jobs to apply later
Smart Job Alerts β set keywords & categories β get email notifications via Resend when matching jobs are posted
Leave company reviews with ratings
Register a company with logo, description, industry, and social links
Post job listings with Tiptap rich text editor for descriptions
Manage listings β edit, pause, close, or delete
View all applicants per job with downloadable resumes
Update applicant status pipeline: pending β reviewed β shortlisted β rejected β hired
Employer dashboard with analytics β total jobs, applicants, and application trends (Recharts)
Platform-wide dashboard with aggregate stats and charts
Manage all users (seekers + employers) β roles & status
Approve or reject company registrations
Moderate all job posts and company reviews
CRUD for job categories
Category
Technology
Purpose
Framework
Next.js 16 (App Router)
SSR/SSG, API routes, middleware, image optimization
UI Library
React 19
Component-based UI
Styling
Tailwind CSS v4
Utility-first CSS
Animations
Framer Motion
Page transitions & micro-interactions
Authentication
NextAuth.js v5 (Auth.js)
Credentials + Google OAuth, JWT sessions
Database
MongoDB + Mongoose 9
Document-based data storage with ODM
Data Fetching
TanStack Query v5 (client) / fetch (server)
Caching, loading states, auto refetch
Forms
React Hook Form + Zod
Validated forms with shared client/server schemas
Rich Text
Tiptap 3
Job description editor (bold, lists, links, headings)
Charts
Recharts
Dashboard analytics visualizations
State Management
Zustand
Resume builder & filter state
File Upload
Cloudinary + Multer
Resume PDFs & company logos
PDF Generation
@react-pdf/renderer
In-app resume β downloadable PDF
Email
Resend + React Email
Job alert & welcome email notifications
Date Utilities
date-fns
Date formatting & manipulation
Notifications
React Hot Toast
Success/error toasts
Icons
React Icons
UI iconography
Deployment
Vercel
Full-stack hosting (frontend + API routes)
Node.js β₯ 18.x
npm β₯ 9.x (or yarn / pnpm )
MongoDB instance (MongoDB Atlas recommended)
Google Cloud project with OAuth credentials
Cloudinary account (Sign up free )
Resend account (Sign up free )
Clone the repository
git clone https://github.com/yourusername/uplink.git
cd uplink
Install dependencies
Set up environment variables
Create a .env file in the root directory (see Environment Variables below).
Start the development server
The app will be available at http://localhost:3000.
npm run build
npm start # Start the production server
π Environment Variables
Create a .env file in the project root with the following variables:
# βββ MongoDB ββββββββββββββββββββββββββββββββββββββ
MONGODB_URI = mongodb+srv://username:password@cluster.mongodb.net/uplink?retryWrites=true&w=majority
# βββ NextAuth βββββββββββββββββββββββββββββββββββββ
NEXTAUTH_URL = http://localhost:3000
NEXTAUTH_SECRET = your_nextauth_secret_key
# βββ Google OAuth βββββββββββββββββββββββββββββββββ
GOOGLE_CLIENT_ID = your_google_client_id
GOOGLE_CLIENT_SECRET = your_google_client_secret
# βββ Cloudinary βββββββββββββββββββββββββββββββββββ
CLOUDINARY_CLOUD_NAME = your_cloud_name
CLOUDINARY_API_KEY = your_api_key
CLOUDINARY_API_SECRET = your_api_secret
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME = your_cloud_name
NEXT_PUBLIC_CLOUDINARY_UPLOAD_PRESET = your_unsigned_preset
# βββ Resend (Email) ββββββββββββββββββββββββββββββ
RESEND_API_KEY = your_resend_api_key
RESEND_FROM_EMAIL = alerts@yourdomain.com
β οΈ Important: Never commit your .env file to version control. It is already included in .gitignore.
uplink/
βββ app/ # Next.js App Router
β βββ layout.jsx # Root layout β fonts, providers, toaster
β βββ globals.css # Global styles & Tailwind imports
β βββ not-found.jsx # Custom 404 page
β βββ loading.jsx # Global loading UI
β β
β βββ (public)/ # π Public pages (SSR/SSG)
β β βββ layout.jsx # Navbar + Footer wrapper
β β βββ page.jsx # Home / Landing page (SSG)
β β βββ about/page.jsx # About page (SSG)
β β βββ jobs/
β β β βββ page.jsx # All jobs listing (SSR)
β β β βββ [id]/page.jsx # Job detail (SSR + generateMetadata)
β β βββ companies/
β β βββ page.jsx # All companies (SSR)
β β βββ [id]/page.jsx # Company profile (SSR + generateMetadata)
β β
β βββ (auth)/ # π Auth pages (centered layout)
β β βββ layout.jsx # Centered card layout
β β βββ login/page.jsx # Login (credentials + Google)
β β βββ register/page.jsx # Register (with role selection)
β β
β βββ dashboard/ # π€ Job Seeker area
β β βββ layout.jsx # Sidebar + content layout
β β βββ page.jsx # Dashboard home β stats & activity
β β βββ applications/page.jsx # My applications tracker
β β βββ saved/page.jsx # Bookmarked jobs
β β βββ alerts/page.jsx # Job alert preferences
β β βββ profile/page.jsx # Edit profile, skills, experience
β β βββ resume/page.jsx # Resume builder (multi-step)
β β
β βββ employer/ # π’ Employer area
β β βββ layout.jsx # Sidebar + content layout
β β βββ dashboard/page.jsx # Employer dashboard β stats & charts
β β βββ company/page.jsx # Edit company profile
β β βββ jobs/
β β βββ page.jsx # Manage posted jobs
β β βββ new/page.jsx # Post new job
β β βββ [id]/
β β βββ edit/page.jsx # Edit existing job
β β βββ applicants/page.jsx # View applicants per job
β β
β βββ admin/ # π‘οΈ Admin area
β β βββ layout.jsx # Sidebar + content layout
β β βββ page.jsx # Admin dashboard β platform stats
β β βββ users/page.jsx # Manage all users
β β βββ companies/page.jsx # Approve/reject companies
β β βββ jobs/page.jsx # Moderate job posts
β β βββ categories/page.jsx # Manage job categories
β β βββ reviews/page.jsx # Manage company reviews
β β
β βββ api/ # β‘ API Route Handlers
β βββ auth/[...nextauth]/route.js # NextAuth handler
β βββ jobs/ # Jobs CRUD + apply
β βββ applications/ # Application tracking
β βββ companies/ # Companies + reviews
β βββ profile/route.js # User profile
β βββ resume/route.js # Resume data
β βββ saved/route.js # Saved/bookmarked jobs
β βββ alerts/ # Job alert preferences
β βββ categories/ # Job categories (admin)
β βββ users/ # User management (admin)
β βββ upload/route.js # Cloudinary file upload
β βββ admin/ # Admin stats & company approval
β
βββ components/ # React Components
β βββ ui/ # Reusable primitives (Button, Input, Badge, Modal, etc.)
β βββ shared/ # Navbar, Footer, Sidebars, Providers
β βββ home/ # Landing page sections
β βββ jobs/ # JobCard, Filters, Search, ApplyModal
β βββ companies/ # CompanyCard, Header, Reviews
β βββ resume/ # ResumeBuilder, StepNav, Preview, PDF
β βββ dashboard/ # Seeker dashboard components
β βββ employer/ # Employer dashboard components
β βββ admin/ # Admin dashboard components
β
βββ lib/ # Server-side utilities
β βββ auth.js # NextAuth v5 config (providers, callbacks)
β βββ db.js # MongoDB singleton connection
β βββ cloudinary.js # Cloudinary upload helper
β βββ resend.js # Resend email client
β βββ templates/ # React Email templates
β βββ utils.js # Shared utility functions
β
βββ models/ # Mongoose schemas (9 models)
βββ schemas/ # Zod validation schemas (shared client + server)
βββ hooks/ # Custom React hooks (TanStack Query wrappers)
βββ store/ # Zustand stores (resume builder, filters)
βββ public/ # Static assets & logos
βββ middleware.js # Next.js edge middleware (auth + role protection)
βββ next.config.mjs # Next.js configuration
βββ postcss.config.mjs # PostCSS configuration
βββ package.json
βββ .gitignore
π Public Pages β Server-Rendered for SEO
Page
Route
Rendering
Description
Home
/
SSG
Hero, featured jobs, top companies, how it works, stats
All Jobs
/jobs
SSR
Full job listings with search, filter, and pagination
Job Detail
/jobs/[id]
SSR
Individual job info, requirements, apply button β SEO meta
All Companies
/companies
SSR
Browse all approved companies
Company Profile
/companies/[id]
SSR
Company info, open positions, reviews β SEO meta
About
/about
SSG
Platform story and mission
Page
Route
Description
Login
/login
Credentials + Google OAuth sign-in
Register
/register
Account creation with role selection (Seeker / Employer)
π€ Job Seeker Dashboard
Page
Route
Description
Dashboard
/dashboard
Overview stats, recent applications
My Applications
/dashboard/applications
All applications with status tracking
Saved Jobs
/dashboard/saved
Bookmarked jobs list
Job Alerts
/dashboard/alerts
Manage keyword/category alert preferences
Profile
/dashboard/profile
Edit personal info, skills, experience, education
Resume Builder
/dashboard/resume
Multi-step form β live preview β downloadable PDF
Page
Route
Description
Dashboard
/employer/dashboard
Job stats, applicant chart, recent applications
Company Profile
/employer/company
Edit company info, logo, social links
Manage Jobs
/employer/jobs
All posted jobs with edit/pause/delete
Post New Job
/employer/jobs/new
Create job listing with Tiptap rich text editor
Edit Job
/employer/jobs/[id]/edit
Modify existing listing
View Applicants
/employer/jobs/[id]/applicants
Applicants per job with status management
Page
Route
Description
Dashboard
/admin
Platform-wide stats and analytics
Manage Users
/admin/users
All users with role/status controls
Manage Companies
/admin/companies
Approve or reject company registrations
Manage Jobs
/admin/jobs
Moderate all job posts
Manage Categories
/admin/categories
CRUD for job categories
Manage Reviews
/admin/reviews
Moderate company reviews
All API routes live under app/api/ and are served from the same Next.js deployment β no separate backend server required .
Access Levels: π Public Β· π€ Seeker Β· π’ Employer Β· π‘οΈ Admin Β· π Authenticated
Method
Endpoint
Access
Description
*
/api/auth/[...nextauth]
π Public
NextAuth.js handler (login, callback, session)
Method
Endpoint
Access
Description
GET
/api/jobs
π Public
Get all jobs (?search, ?category, ?type, ?location, ?salary, ?remote, ?page, ?limit)
POST
/api/jobs
π’ Employer
Create new job post
GET
/api/jobs/[id]
π Public
Get single job detail
PATCH
/api/jobs/[id]
π’ Employer (owner)
Update job post
DELETE
/api/jobs/[id]
π’ Owner / π‘οΈ Admin
Delete job post
POST
/api/jobs/[id]/apply
π€ Seeker
Apply for job
π Applications β /api/applications
Method
Endpoint
Access
Description
GET
/api/applications
π€ Seeker
Get my applications
PATCH
/api/applications/[id]
π’ Employer
Update application status
π’ Companies β /api/companies
Method
Endpoint
Access
Description
GET
/api/companies
π Public
Get all approved companies
POST
/api/companies
π’ Employer
Create company profile
GET
/api/companies/[id]
π Public
Get company detail + open jobs
PATCH
/api/companies/[id]
π’ Employer (owner)
Update company
GET
/api/companies/[id]/reviews
π Public
Get company reviews
POST
/api/companies/[id]/reviews
π€ Seeker
Submit a review
π€ Profile β /api/profile
Method
Endpoint
Access
Description
GET
/api/profile
π€ Seeker
Get my profile
PATCH
/api/profile
π€ Seeker
Update profile (skills, experience, education)
π Resume β /api/resume
Method
Endpoint
Access
Description
GET
/api/resume
π€ Seeker
Get my resume data
POST
/api/resume
π€ Seeker
Save resume builder data
π Saved Jobs β /api/saved
Method
Endpoint
Access
Description
GET
/api/saved
π€ Seeker
Get bookmarked jobs
POST
/api/saved
π€ Seeker
Bookmark a job
DELETE
/api/saved
π€ Seeker
Remove bookmark
π Job Alerts β /api/alerts
Method
Endpoint
Access
Description
GET
/api/alerts
π€ Seeker
Get my job alerts
POST
/api/alerts
π€ Seeker
Create new alert (keywords + categories)
PATCH
/api/alerts/[id]
π€ Seeker
Update alert
DELETE
/api/alerts/[id]
π€ Seeker
Delete alert
π Categories β /api/categories
Method
Endpoint
Access
Description
GET
/api/categories
π Public
Get all categories with job counts
POST
/api/categories
π‘οΈ Admin
Create category
PATCH
/api/categories/[id]
π‘οΈ Admin
Update category
DELETE
/api/categories/[id]
π‘οΈ Admin
Delete category
π₯ Users β /api/users
Method
Endpoint
Access
Description
GET
/api/users
π‘οΈ Admin
Get all users
PATCH
/api/users/[id]
π‘οΈ Admin
Update role or status
DELETE
/api/users/[id]
π‘οΈ Admin
Delete user
π Admin β /api/admin
Method
Endpoint
Access
Description
GET
/api/admin/stats
π‘οΈ Admin
Platform-wide stats for dashboard
PATCH
/api/admin/companies/[id]/approve
π‘οΈ Admin
Approve or reject company registration
βοΈ Upload β /api/upload
Method
Endpoint
Access
Description
POST
/api/upload
π Auth
Upload file to Cloudinary β returns URL
The application uses 9 Mongoose models with a normalized MongoDB schema:
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β User ββββββΆβ Profile β β Category β
β β β (seeker) β β β
β role: β ββββββββββββββββ ββββββββ¬ββββββββ
β jobseeker β β
β employer β ββββββββββββββββ ββββββββΌββββββββ
β admin ββββββΆβ Company ββββββΆβ Job β
β β β (employer) β β β
ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββ¬ββββββββ
β β β
β ββββββββΌββββββββ ββββββββΌββββββββ
β β Review β β Application β
β ββββββββββββββββ ββββββββββββββββ
β
ββββββΆ SavedJob (user + job ref)
ββββββΆ JobAlert (keywords + categories)
Model
Key Fields
Description
User
name, email, password, role, photoURL, isActive
User accounts β jobseeker, employer, admin
Profile
skills, experience[], education[], links
Job seeker extended profile
Company
name, logo, description, industry, size, isApproved
Employer company profile with admin approval
Job
title, description (HTML), category, type, salary, location, deadline
Job listings posted by employers
Application
job, applicant, resumeURL, coverLetter, status
Job applications with status pipeline
SavedJob
user, job
Bookmarked jobs (user β job reference pair)
JobAlert
user, keywords[], categories[]
Email alert subscriptions
Category
name, slug, icon, jobCount
Job categories with associated counts
Review
company, user, rating, comment, isApproved
Company reviews with admin moderation
π Authentication & Authorization
βββββββββββββββ βββββββββββββββ βββββββββββββββ βββββββββββββββ
β Browser ββββββΆβ NextAuth ββββββΆβ MongoDB ββββββΆβ JWT Token β
β β β Providers β β User Lookup β β (session) β
β Login Form β β β β or Create β β β
β Google SSO β β credentials β β β β role stored β
β β β google β β β β in token β
βββββββββββββββ βββββββββββββββ βββββββββββββββ ββββββββ¬βββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββ
β Next.js Middleware β
β β
β /dashboard/* β requires jobseeker role β
β /employer/* β requires employer role β
β /admin/* β requires admin role β
β /login β redirects if already logged in β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Credentials β Email + password (bcrypt hashed)
Google OAuth β One-click Google sign-in
JWT-based sessions β role (jobseeker | employer | admin) embedded in the token
Server components: access session via auth() from lib/auth.js
Client components: access session via useSession() from next-auth/react
Edge Middleware (middleware.js) β intercepts requests before page loads, checks auth + role, redirects unauthorized users
API Routes β additionally verify session via auth() for protected endpoints
π§© Key Technical Highlights
SSR on job & company pages for Google indexing
SSG on static pages (Home, About) for instant loads
generateMetadata for dynamic SEO meta tags
API route handlers β no separate Express server
Edge middleware for auth at the CDN level
next/image for optimized image delivery
Multi-step form (Personal β Experience β Education β Skills β Links)
Live preview panel that updates in real-time
@react-pdf/renderer generates downloadable PDF
PDF uploaded to Cloudinary, URL stored in profile
State managed with Zustand store
Seekers define keywords + categories
New job posts trigger alert matching
Email notifications sent via Resend API
React Email templates for rich HTML emails
Zod schemas in schemas/ folder
Shared between client (React Hook Form resolver) and server (API route validation)
Single source of truth for all validation rules
Type-safe error messages
Contributions are welcome! Here's how you can help:
Fork the repository
Create a feature branch (git checkout -b feature/amazing-feature)
Commit your changes (git commit -m 'Add amazing feature')
Push to the branch (git push origin feature/amazing-feature)
Open a Pull Request
Please make sure to follow the existing code style, use the Zod schemas for any new validation, and test your changes thoroughly.
Distributed under the MIT License . See LICENSE for more information.