Skip to content

M-Chethipuzha/website

Repository files navigation

Mathew Thomas — Personal Portfolio

A fast, accessible, SEO-strong portfolio built with Next.js (App Router) + TypeScript + Tailwind CSS, with MDX blog posts and live GitHub data. No database — all dynamic data comes from the GitHub API through server-side route handlers, cached hourly with ISR.

Quick start

npm install
npm run dev        # http://localhost:3000

That's it. The site runs with zero configuration; a GitHub token just makes it better (see below).

✏️ Editing your content — lib/config.ts

All personal content lives in one file: lib/config.ts. You should never need to touch a component to change what the site says.

What Where in config.ts
Name, role, tagline, bio paragraphs site
GitHub username (⚠️ currently a placeholder — set this first!) site.githubUsername
Email, location, availability badge, résumé link site
Social links (⚠️ LinkedIn/Twitter URLs are placeholders) site.socials
About-section stats highlights
Skill groups & chips skills
Featured project cards featuredProjects
Services cards services

Your résumé PDF is served from public/Mathew-Thomas-Resume.pdf; replace that file to update it.

📝 Adding a blog post

Create content/posts/my-post-slug.mdx with this frontmatter:

---
title: "My post title"
date: "2026-07-01"
excerpt: "One or two sentences shown on cards and in meta descriptions."
tags: ["Go", "Performance"]
readtime: "5 min"
---

Your **MDX** content here.

The post automatically appears on the home page preview, /blog, the sitemap, and gets its own statically-generated page at /blog/my-post-slug with per-post SEO metadata. No registration step.

🔑 GitHub token (optional, recommended)

  1. Create a token at https://github.com/settings/tokens — a classic token with no scopes is enough (public data only).

  2. Copy .env.example to .env.local and set:

    GITHUB_TOKEN=ghp_xxxx
    

What it changes:

Without token With token
Repo cards ✅ works (60 req/h limit) ✅ 5,000 req/h
Contribution heatmap SVG embed from ghchart.rshah.org Native, theme-matched heatmap via the GraphQL API

The token is read only in server code (lib/github.ts) and never reaches the client bundle. GitHub responses are cached with next: { revalidate: 3600 }, so the API is hit at most once per hour per endpoint.

🚀 Deploying to Vercel

  1. Push this repo to GitHub.
  2. vercel.com/new → import the repo → Deploy. No build settings needed; Vercel auto-detects Next.js.
  3. In the Vercel project settings → Environment Variables, add:
    • GITHUB_TOKEN (optional, see above)
    • NEXT_PUBLIC_SITE_URL — your production URL, e.g. https://mathewthomas.dev (used by the sitemap, robots.txt, and Open Graph tags)

Every push to main redeploys. The GitHub sections refresh hourly via ISR without redeploying.

Architecture notes

app/
  layout.tsx                    # fonts, theme provider, global metadata, JSON-LD
  page.tsx                      # home — composes all sections, Suspense for GitHub
  blog/page.tsx                 # post index
  blog/[slug]/page.tsx          # SSG posts (generateStaticParams + generateMetadata)
  api/github/route.ts           # repos JSON (REST, ISR-cached)
  api/github/contributions/route.ts  # heatmap JSON (GraphQL) or fallback URL
  api/subscribe/route.ts        # newsletter stub w/ commented provider integrations
  sitemap.ts / robots.ts
components/                     # one component per section + shared UI
content/posts/*.mdx             # blog posts (gray-matter frontmatter)
lib/
  config.ts                     # ← ALL editable content
  github.ts                     # server-only GitHub fetchers (token stays here)
  posts.ts                      # MDX read/parse helpers
  • GitHub data flow: server components call lib/github.ts directly during render (no self-HTTP round-trip); the /api/github/* routes expose the same data as JSON for client-side or external use.
  • Contributions: GitHub's REST API doesn't expose contribution data, so the heatmap uses the GraphQL contributionsCollection.contributionCalendar query when a token exists, and falls back to the tokenless ghchart.rshah.org SVG when it doesn't. Both paths are commented in components/GithubActivity.tsx.
  • Newsletter: app/api/subscribe/route.ts validates and logs signups; uncomment one of the Buttondown / ConvertKit / Mailchimp blocks and add its API key to .env.local to go live.
  • Dark mode: next-themes with the class strategy — respects system preference, persists the choice, no flash of the wrong theme.
  • Accessibility: semantic landmarks, skip link, focus-visible rings, aria-live form status, keyboard-navigable nav, reduced-motion support.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors