Skip to content

sanderdesnaijer/portfolio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

169 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sanderdesnaijer.com

Live Site Built with Next.js CMS Deployed on Vercel

Personal portfolio and blog of Sander de Snaijer, a frontend developer from the Netherlands with 10+ years of experience.

This site is where code meets creativity: webcam-controlled browser games built with MediaPipe, 3D printing experiments with resin and Arduino, Flutter apps on the App Store, and tutorials about all of it. Built as a fully SEO-optimized Next.js application with structured data, dynamic sitemaps, and tag-based content hubs.

Live at: www.sanderdesnaijer.com

What's on the site

  • Projects / face-controlled Tetris, webcam Duck Hunt with hand tracking, a 3D-printed Arduino word clock, a multi-language Sudoku app, geospatial weather tools, and more
  • Blog / step-by-step guides on 3D printing with resin, MediaPipe hand and face tracking in the browser, building with Next.js and Sanity, Flutter app development, and creative coding
  • Tags / 50+ topic pages that group projects and articles by technology (React, Flutter, MediaPipe, Arduino, 3D printing, etc.)

Tech stack

  • Next.js 16 / App Router, static generation with ISR, dynamic metadata
  • TypeScript / end-to-end type safety
  • Sanity / headless CMS with real-time previews and structured content
  • Tailwind CSS / utility-first styling
  • Playwright / end-to-end testing
  • Jest / unit testing
  • Vercel / deployment with preview branches

SEO features

  • JSON-LD structured data (BlogPosting, FAQPage, Person, WebSite, BreadcrumbList, SoftwareApplication)
  • Open Graph and Twitter Card meta tags with optimized images
  • Dynamic sitemap generation
  • Tag hub pages with unique descriptions and intro content
  • Content-first title strategy for better SERP click-through rates
  • FAQ schema on blog posts for rich result eligibility

Getting started

Copy .env.example to .env.local and fill in the required values:

cp .env.example .env.local

Then run the development server:

npm run dev

Open http://localhost:3000 to see the result.

Project structure

app/           Next.js App Router pages, components, and utilities
sanity/        Sanity schema definitions and studio config
e2e/           Playwright end-to-end tests
messages/      i18n translation files
public/        Static assets and favicons
redirects/     Blog redirect mappings (old Medium slugs)
scripts/       Build and migration scripts

Environment variables

See .env.example for all required variables. You'll need credentials for Sanity, Vercel, and Google site verification.

Exporting blog posts to dev.to

Export a blog post from Sanity to dev.to-compatible markdown:

npm run export:devto -- <slug>

List all available blog post slugs:

npm run export:devto

The exported markdown file lands in scripts/devto-exports/<slug>.md with frontmatter, cover image, tags, and canonical URL pre-filled. Review the content and paste into dev.to/new. Set published: true when ready to go live.

IndexNow

The site supports IndexNow for instant URL submission to Bing, Yandex, and other participating search engines. The verification key is served from public/.

Submit all pages from the sitemap:

node scripts/indexnow.mjs

Submit specific URLs after publishing new content:

node scripts/indexnow.mjs https://sanderdesnaijer.com/blog/my-new-post

Run once per publish. Don't resubmit the same URLs repeatedly.

License

MIT

About

Frontend developer portfolio and blog built with Next.js, Sanity CMS, and TypeScript. Projects include webcam games with MediaPipe, 3D printing experiments, and Flutter apps.

Topics

Resources

Stars

Watchers

Forks

Contributors