Skip to content

Repository files navigation

victormts.dev

Personal portfolio and technical showcase built with Next.js 16 App Router, Sanity CMS, and full i18n support.

Live Site Last Commit

Next.js React TypeScript Tailwind CSS Sanity Vercel


victormts.dev preview

About

This is the source code for victormts.dev, the personal portfolio of Victor M. Santos. It serves a dual purpose: presenting projects, writing, and contact information to clients and recruiters, while demonstrating Next.js App Router patterns in a real production context — i18n with next-intl, ISR via Sanity webhooks, React Server Components, and a design system built on Tailwind v4 OKLCH tokens.

The site is fully bilingual (English and Brazilian Portuguese), statically generated, and deployed on Vercel with incremental revalidation.


Features

  • 🌍 Internationalisationnext-intl v4 with en and pt-BR locales, hreflang on all pages, bilingual Sanity content via coalesce() GROQ fallbacks
  • 📝 CMS — Sanity v6 as headless CMS, Studio embedded at /z-admin/studio, ISR revalidation triggered by Sanity webhooks
  • Performance — Static generation + ISR via cache tags (post, lab), React Compiler enabled, Vercel Analytics
  • 🎨 Design system — Monochromatic OKLCH palette, fluid clamp() type scale, Instrument Serif + Outfit + JetBrains Mono, dark/light mode via next-themes
  • 🔍 SEO — JSON-LD structured data (Person, WebSite, BlogPosting, BreadcrumbList), OG/Twitter cards, dynamic sitemap, /llms.txt for AI crawlers
  • 📬 Contact form — Resend transactional email, Zod v4 validation, in-memory rate limiting (3 req/hour per IP), honeypot anti-bot field
  • 🧪 Lab section — YouTube Data API v3 with full pagination and duration batching, project roadmap, featured project driven by a Sanity settings singleton
  • 🥚 Easter eggs — Konami code, /void interactive terminal, console art, logo click sequence

Tech Stack

Technology Version Role
Next.js 16 Framework — App Router, SSG, ISR, API routes
React 19 UI library, React Compiler enabled
TypeScript 5 Type safety across client and server
Tailwind CSS v4 Utility-first CSS with OKLCH design tokens
Sanity v6 Headless CMS with embedded Studio
next-intl v4 i18n — routing, translations, locale detection
motion v12 Animations (Framer Motion v12)
Resend Transactional email delivery
React Email Email templates as React components
Zod v4 Schema validation for forms and API routes
Radix UI Accessible UI primitives
nuqs Type-safe URL state management
Biome v2 Linting and formatting (replaces ESLint + Prettier)
pnpm Package manager
Vercel Hosting, edge network, analytics

Project Structure

src/
├── app/
│   ├── [locale]/               # All user-facing routes (en / pt-br)
│   │   ├── page.tsx            # Home
│   │   ├── works/              # Devlog post list + individual post pages
│   │   ├── lab/                # Lab — featured project, roadmap, YouTube episodes
│   │   └── void/               # Easter egg — interactive terminal
│   ├── api/
│   │   ├── contact/route.ts    # Contact form — Resend integration + rate limiting
│   │   └── revalidate/route.ts # ISR webhook — Sanity triggers revalidateTag
│   ├── llms.txt/route.ts       # Plain-text description served to AI crawlers
│   └── z-admin/studio/         # Sanity Studio embedded at /z-admin/studio
│
├── components/
│   ├── lab/                    # Lab-specific: roadmap, episode player, build status
│   ├── easter-eggs/            # Console, Konami, logo click, glitch-404
│   └── ui/                     # shadcn/ui primitives
│
├── emails/                     # React Email templates (notification + confirmation)
├── i18n/                       # next-intl routing, request config, typed navigation
├── lib/
│   ├── sanity/                 # Client, GROQ queries, TypeScript types, image helper
│   └── schemas/                # Zod schemas (contact form)
└── proxy.ts                    # next-intl middleware — handles i18n routing

Environment Variables

Variable Scope Description
NEXT_PUBLIC_SANITY_PROJECT_ID Public Sanity project ID
NEXT_PUBLIC_SANITY_DATASET Public Dataset name — production or development
SANITY_API_TOKEN Server only Read token for server-side Sanity fetches
RESEND_API_KEY Server only API key for contact form email delivery
YOUTUBE_API_KEY Server only YouTube Data API v3 key for Lab playlist
REVALIDATE_SECRET Server only Shared secret for the Sanity ISR webhook
NEXT_PUBLIC_SITE_URL Public Canonical base URL, e.g. https://victormts.dev

Sanity CMS

The project uses five schemas defined in sanity.config.ts:

Schema Type Description
post Document Devlog posts — title, slug, tags, reading time, Portable Text body with code blocks
labProject Document Lab projects — name, type, roadmap, tech stack, GitHub repo, live URL
roadmapStep Object Embedded in labProject — phase number, title, description, status
labStatus Singleton Free-text status of current Lab work, auto-dated on save
labSettings Singleton Featured project reference + YouTube playlist ID

ISR Revalidation

On every document publish, Sanity triggers a webhook to POST /api/revalidate?secret=<REVALIDATE_SECRET>. The endpoint calls revalidateTag("post") or revalidateTag("lab") based on _type, invalidating only the affected cache.


© 2026 Victor M. Santos — All rights reserved. This repository is public for viewing purposes only. Cloning, forking, or reusing the code without explicit permission is not allowed.

Releases

Packages

Contributors

Languages