This repository contains a personal portfolio website (frontend + backend). The frontend is a Vite + React + TypeScript app styled with Tailwind CSS. The backend is a small Express + Mongoose API that serves portfolio data from MongoDB Atlas.
Live demo
- Frontend: (deployed to Cloudflare Pages) — your public site URL
- Backend: (deployed to Render) — e.g.
https://portfolio-website-k9t9.onrender.com
Tech stack
- Frontend: React, Vite, TypeScript, Tailwind CSS
- Backend: Node.js (ES modules), Express, Mongoose (MongoDB Atlas)
- Deployment: Cloudflare Pages (frontend), Render (backend)
Repository layout
/
README.md
package.json # frontend (root)
src/ # frontend source
backend/
index.js # express + mongoose server
package.json
.env (local only)
Environment variables
- Backend (on Render or local):
MONGO_URL— MongoDB Atlas connection string (do NOT commit this to git)PORT(optional) — port for Express (Render provides $PORT automatically)
- Frontend (at build time):
VITE_API_URL— the public base URL of the backend (e.g.https://portfolio-website-k9t9.onrender.com). This must be set in your static host's build environment (Cloudflare Pages / Vercel / Netlify) because Vite injectsimport.meta.env.VITE_*at build time.
Local development
- Install dependencies
Frontend (repo root):
npm ciBackend (backend folder):
cd backend
npm ci- Run locally
Start backend (uses backend/.env via dotenv on local runs):
cd backend
# either use your local .env with MONGO_URL set, or run inline:
MONGO_URL="mongodb+srv://<user>:<password>@.../yourdb?retryWrites=true&w=majority" PORT=5000 npm startStart frontend (in repo root):
npm run dev
# open http://localhost:5173 (Vite default)Building & deploying
Frontend (Cloudflare Pages / other static host):
- Ensure the environment variable
VITE_API_URLis set in your host's build settings to your backend URL (e.g.https://portfolio-website-k9t9.onrender.com). Then trigger a build/deploy.
Backend (Render recommended for this project):
- Create a Web Service on Render and set Service Root Directory to
backend. - Start Command:
npm start - Environment variables on Render: set
MONGO_URLto your Atlas connection string (do NOT include creds in repo). Optionally setPORT.
Important: Vite inlines import.meta.env.VITE_* during the build. Changing environment variables on the host without rebuilding will not change the values your app uses. Always rebuild the frontend after updating VITE_API_URL.
Troubleshooting
-
Unexpected token '<' when fetching JSON
- Cause: frontend requested an HTML page (the static host) instead of the backend API. Usually because
VITE_API_URLwas not set at build time or pointed to the wrong origin. - Fix: set
VITE_API_URLin your host's build environment and rebuild the site.
- Cause: frontend requested an HTML page (the static host) instead of the backend API. Usually because
-
Double slash in request (e.g.
https://...//api/portfolio)- Cause:
VITE_API_URLended with a trailing slash and the code added another slash before the/apipath. - Fix: remove trailing slash from
VITE_API_URLin the environment (usehttps://example.comnothttps://example.com/).
- Cause:
-
MongoDB TLS / connection issues on hosts (e.g. SSL/TLS handshake errors)
- Common causes: Atlas IP Access List blocking the host, SRV vs Standard connection string differences, DNS/IPv6 handshake issues.
- Quick test: temporarily add
0.0.0.0/0to Atlas Network Access (IP Access List) to verify connectivity from the host. If that fixes it, tighten the rule later. - Alternative: use Atlas “Standard connection string” (non-SRV) if SRV causes problems.
-
Ensure
MONGO_URLon the host includes a DB name and valid options, for example:mongodb+srv://user:password@cluster0.oni88ky.mongodb.net/portfolio?retryWrites=true&w=majority
Safety & secrets
- Never commit
MONGO_URLor other secrets to your repository. Use the host's environment variables/secret store. - Rotate credentials if a secret was accidentally committed.
Contact / Next steps
- If you want, I can:
- Add more robust serverless handlers (Vercel/Cloudflare Workers) to serve the API.
- Add automated CI (GitHub Actions) to build the frontend with secrets during deploy.
License
- This project is MIT licensed — adapt as needed.
Welcome to the ultimate starter template for React with Vite! Get ready for blazing-fast development with Hot Module Replacement (HMR) and some handy ESLint rules.
Choose your weapon for Fast Refresh:
- @vitejs/plugin-react - Powered by Babel
- @vitejs/plugin-react-swc - Supercharged by SWC
Follow these simple steps to get your project up and running:
-
Clone the repository:
git clone https://github.com/your-username/your-repo-name.git cd your-repo-name -
Install dependencies:
npm install
-
Run the development server:
npm run dev
-
Build for production:
npm run build
-
Preview the production build:
npm run serve
Here's a quick overview of the project layout:
├── public
│ └── index.html
├── src
│ ├── assets
│ ├── components
│ ├── App.jsx
│ ├── main.jsx
│ └── index.css
├── .gitignore
├── index.html
├── package.json
├── README.md
├── vite.config.js
└── yarn.lock
Dive deeper into the world of Vite and React with these awesome resources:
- Vite Documentation
- React Documentation
- Vite Plugins
- React Router
- React Context
- React Hooks
- Styled Components
- ESLint
- Prettier
- Aceternity UI
This project is licensed under the MIT License - see the LICENSE file for details.
Happy coding! 🎉