π Live Demo: mystery-message-roby.vercel.app
π£ LinkedIn Post: mystery-message-linkedin-post
π¬ Send Me a Feedback here: mystery-message-roby.vercel.app/u/codebydurvesh
Mystery Message is a full-stack anonymous feedback platform built with Next.js. Users sign up, get a unique shareable profile link, and anyone β logged in or not β can send them anonymous messages through that link. The receiver can manage which messages they accept, view all received messages, and delete individual ones β all without senders ever revealing who they are.
- Sign Up with a unique username, email, and password
- Real-time username availability check (debounced) as you type
- Email OTP verification via Resend β a 6-digit code is sent to your inbox after sign-up
- Sign In with credentials through NextAuth.js
- Protected routes β unauthenticated users are redirected to
/signin; unverified users are redirected to/verify/:username
- Every user gets a unique public profile URL:
/u/<username> - Anyone (no account required) can visit this URL and send an anonymous message
- Messages are limited to 300 characters with a live character counter
- The sender's identity is never stored or revealed
- On the send-message page, users can fetch AI-suggested question prompts to inspire their anonymous messages
- Three random question suggestions are served from a curated dataset via
/api/suggest-messages
- View all received messages in a responsive card grid (1 / 2 / 3 columns)
- Delete individual messages with a single click (with instant UI update)
- Copy your unique profile link to clipboard with one click
- Toggle message acceptance β turn off incoming messages with a toggle switch; senders are notified the user is not accepting messages
- Unverified users see a prompt to verify their account before they can toggle message acceptance
- Built with shadcn/ui components (Card, Button, Switch, Separator, Form, Input, etc.)
- Dark / light mode support via
next-themes - Animated carousel on the homepage showcasing sample anonymous messages (auto-plays every 2 seconds)
- Subtle conic-gradient animated button on the landing page
- Toast notifications (via Sonner) for all success and error events
- Fully responsive layout β mobile-first design
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β NEW USER FLOW β
β β
β 1. Visit /signup β
β ββ Enter username (real-time uniqueness check), email, β
β and password β Submit β
β β
β 2. Account created (unverified) β Redirected to /verify/:user β
β ββ OTP email sent via Resend β
β β
β 3. Enter 6-digit OTP on /verify/:username β
β ββ Account marked as verified β Redirected to /dashboard β
β β
β 4. Dashboard loads: β
β ββ Profile link displayed & copyable β
β ββ Accept Messages toggle (ON by default) β
β ββ Message grid (empty for a new user) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SENDER FLOW β
β β
β 1. Receive a shared link β /u/<username> β
β β
β 2. Type an anonymous message (up to 300 chars) β
β ββ Optionally click "Suggest" for AI-generated prompts β
β β
β 3. Hit "Send Message" β
β ββ If user is accepting β message saved, success toast β
β ββ If user is not accepting β error shown to sender β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RETURNING USER FLOW β
β β
β 1. Visit /signin β Enter credentials β Redirected to /dashboardβ
β β
β 2. Dashboard shows all received messages β
β ββ Click "Copy" to copy profile URL β
β ββ Toggle acceptance on/off β
β ββ Delete any message β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Layer | Technology |
|---|---|
| Framework | Next.js 15 (App Router) |
| Language | TypeScript |
| Database | MongoDB via Mongoose |
| Auth | NextAuth.js v4 (Credentials provider) |
| Resend + React Email | |
| UI Components | shadcn/ui + Radix UI |
| Styling | Tailwind CSS v4 |
| Forms | React Hook Form + Zod |
| Carousel | Embla Carousel with Autoplay |
| HTTP Client | Axios |
| Toasts | Sonner |
| Password Hashing | bcryptjs |
| Deployment | Vercel |
src/
βββ app/
β βββ (app)/
β β βββ page.tsx # Landing page with carousel
β β βββ layout.tsx # App layout with Navbar
β β βββ dashboard/page.tsx # User dashboard
β β βββ u/[username]/page.tsx # Public send-message page
β βββ (auth)/
β β βββ signin/page.tsx # Sign in form
β β βββ signup/page.tsx # Sign up form
β β βββ verify/[username]/page.tsx # OTP verification
β βββ api/
β βββ auth/[...nextauth]/ # NextAuth route handler
β βββ signup/ # Register new user + send OTP
β βββ verify-code/ # Validate OTP
β βββ chech-username-unique/# Check username availability
β βββ accept-messages/ # GET/POST toggle acceptance
β βββ send-message/ # Send anonymous message
β βββ get-messages/ # Fetch all messages for user
β βββ delete-message/ # Delete a specific message
β βββ suggest-messages/ # Return random question prompts
βββ model/
β βββ User.ts # Mongoose User + Message schema
βββ schemas/ # Zod validation schemas
βββ components/
β βββ Navbar.tsx
β βββ MessageCard.tsx
β βββ ui/ # shadcn/ui components
βββ emails/
β βββ VerificationEmail.tsx # React Email OTP template
βββ helpers/ # sendVerificationEmail helper
βββ lib/ # dbConnect, auth options
βββ data/ # Sample messages & question sets
βββ types/ # ApiResponse type
βββ middleware.ts # Route protection logic
- Node.js 18+
- A MongoDB database (Atlas free tier works)
- A Resend account and API key
git clone https://github.com/codebydurvesh/mystery-message.git
cd mystery-messagenpm installCopy .env.example to .env and fill in your values:
cp .env.example .envMONGO_URI=your_mongodb_connection_string
RESEND_API_KEY=your_resend_api_key
NEXT_AUTH_SECRET=a_long_random_secret_stringnpm run devOpen http://localhost:3000 in your browser.
| Method | Endpoint | Auth Required | Description |
|---|---|---|---|
POST |
/api/signup |
β | Register a new user; sends OTP email |
POST |
/api/verify-code |
β | Verify OTP and activate account |
GET |
/api/chech-username-unique |
β | Check if a username is available |
GET |
/api/accept-messages |
β | Get current accept-messages setting |
POST |
/api/accept-messages |
β | Toggle accept-messages on/off |
POST |
/api/send-message |
β | Send an anonymous message to a user |
GET |
/api/get-messages |
β | Retrieve all messages for the signed-in user |
DELETE |
/api/delete-message/:id |
β | Delete a specific message by ID |
GET |
/api/suggest-messages |
β | Get 3 random AI-style question suggestions |
- Passwords are hashed with bcryptjs before storage β plain-text passwords are never saved
- OTP codes are time-limited (stored with an expiry date)
- Route-level protection is enforced in middleware.ts β unauthenticated and unverified users are automatically redirected
- Session tokens are signed using
NEXT_AUTH_SECRET
This project is open-source and available under the MIT License.
Made by Durvesh