Personal portfolio of Muhammad Ramazan, Full Stack Software Engineer. Live at mramazan.dev.
Built with Next.js 15 (App Router), TypeScript and Tailwind CSS. The page is statically rendered, supports light and dark themes, and ships very little client-side JavaScript.
All copy lives in one file: src/data/profile.ts. Experience, skills, testimonials, education and certifications are plain data, so updating the site rarely means touching a component.
- Résumé:
public/CV.pdfis generated from the same data. After editingprofile.ts, runnpm run cv(needspdflatexwith thefontawesome5,paracolandtitlesecpackages, e.g. TeX Live). It writescv/cv.texfrom the layout incv/preamble.texand copies the compiled PDF topublic/CV.pdf. ThephoneandcvSummaryfields inprofile.tsare used only by the CV. - Certificates: add images to
public/certificates/and reference them fromcertificatesinprofile.ts.
src/
app/ layout, page, Open Graph image, sitemap, robots
components/sections/ one component per page section
components/ui/ small shared pieces (theme toggle, contact form, certificate viewer, ...)
data/profile.ts all site content
cv/ generated LaTeX CV (preamble.tex is the hand-written layout)
scripts/generate-cv.mts builds cv/cv.tex from profile.ts
npm install
cp env-example .env # optional: contact form and analytics
npm run dev| Variable | Purpose |
|---|---|
NEXT_PUBLIC_EMAILJS_SERVICE_ID, NEXT_PUBLIC_EMAILJS_TEMPLATE_ID, NEXT_PUBLIC_EMAILJS_PUBLIC_KEY |
Contact form delivery via EmailJS. Template params: from_name, from_email, reply_to, message, to_email. |
NEXT_PUBLIC_POSTHOG_KEY, NEXT_PUBLIC_POSTHOG_HOST |
Optional PostHog analytics. Skipped when the key is not set. |
npm run lint
npm run build