A stunning portfolio website with an innovative liquid glass navigation, full-featured blog, and comprehensive admin dashboard.
- Features
- Tech Stack
- Getting Started
- Environment Variables
- Railway Deployment
- Creating Admin User
- API Reference
- Project Structure
- License
A unique, Apple-inspired navigation system with stunning visual effects:
- Glassmorphism Design - Frosted glass effect with backdrop blur
- Animated Hover Bubble - Smooth liquid-like hover animations
- Moving Indicator - Active page indicator with fluid transitions
- Touch Support - Long-press and drag navigation on mobile devices
- SVG Filters - Custom gooey effect using SVG filters
| Page | Features |
|---|---|
| Home | Hero section, featured projects, skills showcase, testimonials |
| Blog | 3-column grid, categories, tags, search, reading time estimates |
| Blog Post | Markdown rendering, syntax highlighting, table of contents, related posts |
| About | Bio, experience timeline, skills with progress bars, downloadable resume |
| Contact | Contact form, social links, location info |
- Markdown Editor - Rich text editing with live preview
- Syntax Highlighting - Code blocks with language detection
- Categories & Tags - Organize posts with multiple taxonomies
- Featured Posts - Highlight important articles
- Reading Time - Automatic calculation based on content
- SEO Optimized - Meta tags, Open Graph, structured data
Complete content management system with:
| Section | Capabilities |
|---|---|
| Dashboard | Analytics overview, recent activity, quick stats |
| Blog Manager | Create, edit, delete posts; manage drafts; bulk actions |
| File Manager | Upload images/files, organize media, copy URLs |
| Comments | Moderate comments, approve/reject, spam filtering |
| Profile | Update bio, social links, avatar, resume |
| Security | 2FA setup (TOTP), passkey/WebAuthn, email OTP |
- JWT Authentication - Secure token-based auth
- Two-Factor Authentication - TOTP (Google Authenticator)
- Passkey Support - WebAuthn/FIDO2 passwordless login
- Email OTP - One-time password via email
- Rate Limiting - Brute force protection
- CORS Protection - Configurable origins
- Security Headers - XSS, CSRF, clickjacking protection
- Dark Theme - Elegant dark mode with purple accents
- Fully Responsive - Mobile-first design
- Fast Performance - Optimized images, lazy loading
- SEO Ready - Meta tags, sitemaps, robots.txt
- Terminal Footer - Unique CLI-style footer with live stats
- File Storage - Persistent volume storage on Railway
| Layer | Technology |
|---|---|
| Frontend | Next.js 14, React 18, Tailwind CSS, shadcn/ui |
| Backend | FastAPI, Python 3.11, Pydantic, Motor |
| Database | MongoDB Atlas |
| Storage | Railway Volume |
| Deployment | Railway |
- Node.js 18+
- Python 3.11+
- MongoDB (local or Atlas)
- Yarn package manager
-
Clone the repository
git clone https://github.com/gupta-8/nextjs-blog.git cd nextjs-blog -
Install frontend dependencies
cd frontend yarn install -
Install backend dependencies
cd ../backend pip install -r requirements.txt -
Set up environment variables (see Environment Variables)
-
Start the development servers
Backend:
cd backend uvicorn server:app --reload --host 0.0.0.0 --port 8001Frontend:
cd frontend yarn dev
| Variable | Required | Description | Example |
|---|---|---|---|
MONGODB_URI |
✅ Yes | MongoDB connection string | mongodb+srv://cxx:xxx@cluster.xxx/db |
DB_NAME |
✅ Yes | Database name | portfolio |
JWT_SECRET_KEY |
✅ Yes | Secret key for JWT (min 32 chars) | ${{ secret() }} |
CORS_ORIGINS |
✅ Yes | Frontend URL (comma-separated) | https://your-frontend.up.railway.app |
| Variable | Required | Description | Example |
|---|---|---|---|
NEXT_PUBLIC_BACKEND_URL |
✅ Yes | Backend API URL | https://your-backend.up.railway.app |
This project uses Nixpacks (Railway's auto-detection) for deployment - no Dockerfile needed!
- Go to railway.app
- Click "Login" → "Login with GitHub"
- Authorize Railway to access your GitHub
- Click "New Project"
- Select "Empty Project"
- Name your project (e.g.,
portfolio)
Option A: Railway MongoDB (Easiest)
- In your project, click "+ New"
- Select "Database" → "MongoDB"
- Wait for it to provision
- The
MONGODB_URIwill be available as a reference variable
Option B: MongoDB Atlas (Free Tier)
- Go to mongodb.com/atlas
- Create free cluster (M0)
- Network Access → Add
0.0.0.0/0 - Database Access → Create user
- Connect → Drivers → Copy connection string
- In your Railway project, click "+ New"
- Select "GitHub Repo"
- Choose your repository
- In Settings → Build → Set Root Directory:
backend - Railway will auto-detect Python and build with Nixpacks
Add Environment Variables:
Click on the backend service → "Variables" tab → "+ New Variable"
| Variable | Value |
|---|---|
MONGODB_URI |
${{MongoDB.MONGODB_URI}} or your Atlas connection string |
DB_NAME |
portfolio |
JWT_SECRET_KEY |
${{ secret() }} (Railway auto-generates) |
CORS_ORIGINS |
https://your-frontend.up.railway.app (add after frontend deploy) |
Generate Domain:
- Click "Settings" tab
- Under "Networking" → Click "Generate Domain"
- Copy the URL (e.g.,
your-backend-xyz.up.railway.app)
- Click "+ New" → "GitHub Repo"
- Choose the same repository
- In Settings → Build → Set Root Directory:
frontend - Railway will auto-detect Next.js and build with Nixpacks
Add Environment Variables:
| Variable | Value |
|---|---|
NEXT_PUBLIC_BACKEND_URL |
https://your-backend-xyz.up.railway.app |
Generate Domain:
- Click "Settings" tab
- Under "Networking" → Click "Generate Domain"
- Copy the URL (e.g.,
your-frontend-abc.up.railway.app)
Go back to your backend service → "Variables" → Update:
| Variable | Value |
|---|---|
CORS_ORIGINS |
https://your-frontend-abc.up.railway.app |
The backend will automatically redeploy.
-
Click on frontend service → "Settings"
-
Under "Networking" → "Custom Domain"
-
Enter your domain:
yourdomain.com -
Add DNS records at your registrar:
Type Name Value CNAME @ your-frontend-abc.up.railway.appCNAME www your-frontend-abc.up.railway.app -
Wait for DNS propagation (5-30 minutes)
-
Update environment variables with your custom domain
- Click on backend service → "Volumes"
- Click "+ New Volume"
- Mount path:
/uploads - The backend will redeploy with persistent storage
After deployment, you have two options to create your admin account:
Simply visit your setup page:
https://your-frontend-abc.up.railway.app/setup
You'll see a beautiful setup form where you can enter:
- Full Name - Your display name
- Email Address - Your admin email
- Password - Minimum 8 characters
After creating your account, you'll be redirected to the login page.
⚠️ Note: The setup page only works when no admin account exists. After the first admin is created, this page will redirect to login.
curl -X POST https://your-backend-xyz.up.railway.app/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "admin@example.com",
"password": "YourSecurePassword123!",
"name": "Admin"
}'Expected Response:
{
"id": "abc123",
"email": "admin@example.com",
"name": "Admin"
}http POST https://your-backend-xyz.up.railway.app/api/auth/register \
email=admin@example.com \
password=YourSecurePassword123! \
name=Adminfetch('https://your-backend-xyz.up.railway.app/api/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'admin@example.com',
password: 'YourSecurePassword123!',
name: 'Admin'
})
}).then(r => r.json()).then(console.log);- Go to
https://your-frontend-abc.up.railway.app/admin - Enter your email and password
- Start managing your portfolio!
⚠️ Note: After creating the first user, registration is automatically disabled for security.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/auth/register |
Register new user |
POST |
/api/auth/login |
Login and get JWT token |
GET |
/api/auth/me |
Get current user info |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/health |
Health check |
GET |
/api/profile |
Get public profile |
GET |
/api/blogs |
List all published posts |
GET |
/api/blogs/{slug} |
Get single post by slug |
GET |
/api/projects |
List all projects |
GET |
/api/skills |
List all skills |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/admin/blogs |
List all posts (including drafts) |
POST |
/api/admin/blogs |
Create new post |
PUT |
/api/admin/blogs/{id} |
Update post |
DELETE |
/api/admin/blogs/{id} |
Delete post |
POST |
/api/upload |
Upload file |
GET |
/api/admin/files |
List uploaded files |
DELETE |
/api/admin/files/{filename} |
Delete file |
nextjs-blog/
├── 📄 README.md
│
├── 📂 backend/
│ ├── 📄 Dockerfile # Docker configuration
│ ├── 📄 railway.toml # Railway configuration
│ ├── 📄 server.py # FastAPI application
│ ├── 📄 auth.py # JWT authentication
│ ├── 📄 requirements.txt # Python dependencies
│ │
│ ├── 📂 routes/
│ │ ├── admin_routes.py # Admin API endpoints
│ │ ├── auth_routes.py # Authentication endpoints
│ │ └── security_routes.py # 2FA, passkey endpoints
│ │
│ ├── 📂 storage/
│ │ └── blob_storage.py # File storage
│ │
│ └── 📂 utils/
│ ├── crypto.py # Encryption utilities
│ └── rate_limiter.py # Rate limiting
│
└── 📂 frontend/
├── 📄 Dockerfile # Docker configuration
├── 📄 railway.toml # Railway configuration
├── 📄 next.config.js # Next.js configuration
├── 📄 package.json
│
├── 📂 app/ # Next.js App Router
│ ├── layout.js
│ ├── page.js
│ ├── 📂 (public)/ # Public routes
│ └── 📂 admin/ # Admin routes
│
├── 📂 src/
│ ├── 📂 components/
│ │ ├── 📂 liquid-glass/ # Liquid glass navigation
│ │ ├── 📂 ui/ # shadcn/ui components
│ │ └── 📂 editor/ # Blog editor
│ │
│ ├── 📂 views/ # Page components
│ ├── 📂 hooks/ # Custom React hooks
│ └── 📂 contexts/ # React contexts
│
└── 📂 public/ # Static assets
Build Fails on Railway
- Check build logs in Railway dashboard
- Verify Dockerfile is in the correct directory
- Ensure all dependencies are in requirements.txt / package.json
MongoDB Connection Error
- Verify
MONGODB_URIis correct - For Atlas: Ensure
0.0.0.0/0is in Network Access - Check database user has read/write permissions
CORS Errors
- Ensure
CORS_ORIGINSincludes your frontend URL - Include the full URL with
https:// - Redeploy backend after updating
File Upload Not Working
- Add a volume to backend service (mount:
/uploads) - Redeploy the backend service
Admin Login Fails
- Ensure you've created an admin user via cURL
- Check
JWT_SECRETis set - Verify backend is running (check health endpoint)
This project is licensed under the MIT License - see the LICENSE file for details.