A production-ready personal portfolio built with Next.js 14 (App Router), TypeScript, and Tailwind CSS. Every piece of personal content — profile info, projects, skills, certifications, experience, and education — lives in typed data files under src/data/, so the site can be updated without touching any component markup.
This site is a single-page portfolio (/) with sticky navigation, scroll-spy active states, an animated terminal hero, categorized skills, case-study project cards with an accessible modal, tiered certifications, and a contact form that opens a pre-filled email draft (no backend required).
All content is sourced strictly from the resume and GitHub profile provided during development. Where information wasn't available (e.g. a public repo for a project, a certification credential URL, a live demo), the site intentionally omits it rather than inventing it — see Content accuracy below.
- Sticky, accessible navbar with scroll-spy active-section highlighting and a mobile hamburger menu
- Animated terminal-style hero (respects
prefers-reduced-motion) - Categorized skills — no fabricated proficiency percentages
- Featured project case studies in an accessible modal (Escape to close, focus trap, click-outside to close)
- Additional projects shown without a GitHub button when no public repo exists
- Tiered certifications (featured / technical / additional)
- Contact form that opens a pre-filled
mailto:draft — swappable for Formspree/Web3Forms (see below) - Full keyboard navigation and visible focus states throughout
- Self-hosted fonts (no runtime call to Google Fonts — see Fonts)
- SEO metadata, Open Graph/Twitter cards,
sitemap.xml,robots.txt - Fully responsive from 360px to large desktop
- Next.js 14 (App Router) + TypeScript
- Tailwind CSS for styling (custom design tokens — see
tailwind.config.ts) - lucide-react for icons
- Fontsource (self-hosted Space Grotesk, Inter, JetBrains Mono)
- No external UI framework — components are hand-built for a distinctive look
advith-portfolio/
├── public/
│ ├── favicon.svg
│ ├── robots.txt
│ └── resume.pdf ← you need to add this (see below)
├── src/
│ ├── app/
│ │ ├── layout.tsx # fonts, metadata, Navbar/Footer shell
│ │ ├── page.tsx # assembles all sections
│ │ ├── globals.css # design tokens, base styles, utility classes
│ │ └── sitemap.ts
│ ├── components/
│ │ ├── Navbar.tsx
│ │ ├── Hero.tsx
│ │ ├── About.tsx
│ │ ├── Skills.tsx
│ │ ├── Projects.tsx
│ │ ├── ProjectCard.tsx
│ │ ├── ProjectModal.tsx
│ │ ├── Experience.tsx
│ │ ├── Certifications.tsx
│ │ ├── Education.tsx
│ │ ├── Contact.tsx
│ │ ├── Footer.tsx
│ │ ├── SectionHeading.tsx
│ │ └── ScrollReveal.tsx
│ ├── data/
│ │ ├── profile.ts # name, contact info, links, nav
│ │ ├── projects.ts # all project content
│ │ ├── skills.ts
│ │ ├── certifications.ts
│ │ └── experience.ts # Secure Hub MGIT + achievement
│ └── lib/
│ └── utils.ts # cn() className helper
├── tailwind.config.ts
├── next.config.mjs
├── tsconfig.json
└── package.json
Requires Node.js 18.18+ (built and tested on Node 22).
npm installnpm run devVisit http://localhost:3000.
npm run build
npm run startnpm run build has been run and verified for this project: it type-checks with tsc --noEmit, lints clean with next lint, and produces a static, prerendered page (○ in the build output — no server-only routes).
- Push this project to a GitHub repository (see naming suggestion below).
- Go to vercel.com/new and import the repository.
- Framework preset: Vercel auto-detects Next.js — no configuration needed.
- No environment variables are required for the current feature set (the contact form uses
mailto:, not an API). - Click Deploy.
- Once live, add a custom domain from the Vercel project's Settings → Domains tab if you have one.
- Update
siteUrlinsrc/app/layout.tsxandsrc/app/sitemap.ts(currently a placeholder) to your real deployed URL, then redeploy — this powers canonical URLs and social share previews.
Suggested repository name: advith-portfolio or portfolio.
Everything personal lives in src/data/:
| File | Controls |
|---|---|
profile.ts |
Name, role, tagline, email, phone, GitHub, LinkedIn, resume path, nav links, about copy |
projects.ts |
All project content — title, description, problem/solution, tech stack, GitHub link |
skills.ts |
Skill categories and items |
certifications.ts |
Certifications and their tier (primary / technical / additional) |
experience.ts |
Secure Hub MGIT experience + the Smart Coder achievement |
education.ts |
Degree, institution, CGPA, status |
No component file needs to change for routine content updates.
Edit src/data/projects.ts. Each project has a featured: boolean — featured projects render as large case-study cards up top; the rest render in a smaller "Additional Projects" grid. A project without a github field automatically hides its GitHub button rather than showing a broken or fake link — do not add a placeholder URL here; leave the field out until a real repository exists.
Export your resume as a PDF and place it at:
public/resume.pdf
The "Download Resume" buttons in the hero and contact section already link to /resume.pdf — they'll work as soon as the file exists. No file is currently present (see Information still needed).
Edit the email, github, and linkedin fields in src/data/profile.ts.
The form currently builds a mailto: link client-side — no data is sent anywhere. To collect submissions server-side instead:
- Sign up for Formspree or Web3Forms and get a form endpoint/access key.
- In
src/components/Contact.tsx, replace thehandleSubmitfunction'smailto:logic with afetch()POST to your endpoint. - If the provider needs a secret key, add it to a new
.env.localfile (NEXT_PUBLIC_FORM_ENDPOINT=...) and add the same variable in Vercel's Settings → Environment Variables. Never commit.env.local.
Fonts are self-hosted via Fontsource (@fontsource/space-grotesk, @fontsource/inter, @fontsource/jetbrains-mono) rather than next/font/google. This was a deliberate choice made after verifying the build in a network-restricted environment where fonts.googleapis.com wasn't reachable — self-hosting also means one less runtime dependency on Google's CDN in production, and identical results everywhere the project is built.
Every fact on this site — name, education, projects, certifications, experience, achievement — was taken directly from the resume and public GitHub profile (github.com/advith-crypto) used to build it. Specifically, the build process did not invent:
- Job titles, employers, or clients (Secure Hub MGIT is presented as club/community experience, not employment)
- Project metrics, model accuracy, or dataset sizes
- GitHub stars, forks, or contributor counts
- Live demo URLs or screenshots for projects that don't have them
- Credential IDs or verification URLs for certifications
- A LinkedIn URL (uses the one explicitly provided)
Two projects — Blood Bank Management System and AgriVision — appear as text-only entries without a GitHub button because no public repository exists for either at the time of writing. If you publish repos for these later, add a github field to their entry in src/data/projects.ts.
-
public/resume.pdf— add your resume PDF at this path; the download buttons are already wired up - Live site URL — once deployed, update the
siteUrlplaceholder insrc/app/layout.tsxandsrc/app/sitemap.ts - Project demo URLs — none are currently listed; add a
liveDemofield inprojects.tsonly once something is actually deployed - Project screenshots — currently using UI-based visual treatments instead of real screenshots; swap in real ones if you have them
- Certification credential URLs — none were provided; add a
urlfield per certification incertifications.tsif you have official verification links - Custom domain — optional, configure in Vercel if desired
npm audit flags four high-severity advisories in Next.js 14.2.35 related to Server Actions, custom servers, and rewrites (GHSA-m99w-x7hq-7vfj and related). This site uses none of those features — no Server Actions, no custom server, no rewrites — so the vulnerable code paths aren't reachable here. The fix requires upgrading to Next.js 16, a major version with breaking changes; that upgrade is left for you to do deliberately once you're ready to test it, rather than forced into this build.
Personal portfolio — content and code © Thota Advith. Feel free to fork the structure for your own portfolio, but please swap in your own content.