
piccolopellegrino.dev
Website · Released Oct 2026
My personal portfolio: a statically exported Next.js site powered by Sanity, where every project is presented as a small case study with architecture and technical decisions.
01 — Gallery
The app, screen by screen
A look at the main screens of the app.




02 — Architecture
How it's built
The app, layer by layer. Each badge links to the decision that shaped that layer.
BUILD PIPELINE
Sanity Studio
Content editing
Content Lake
Sanity · GROQ API
Next.js build
Static export
Static site
Pre-rendered pages
Contact form
Third-party form endpoint
Application server
No server, no API routes
03 — Decisions
Decision log
Context, choice and the price paid for each one.
Static export instead of server rendering
Context
Content changes rarely and the site has no user-specific data.
Decision
Build the whole site with Next.js output: "export" and serve it as static files.
Tradeoff
Content updates need a rebuild, and server features (API routes, image optimization) aren't available.
Alternatives
SSR on a Node server, ISR on Vercel
Sanity as headless CMS
Context
Each project is a structured case study (layers, decisions, gallery), which is awkward to maintain in Markdown files.
Decision
Model projects in Sanity with typed fields and validation, edited in a custom Studio.
Tradeoff
It adds an external dependency, and content lives outside the repository.
Alternatives
MDX files in the repo, JSON files
One-click rebuild from the Studio
Context
A static site has to be rebuilt to show new content.
Decision
A custom "Update Site" tool in the Studio triggers a build only when I decide, protected by a password.
Tradeoff
Publishing and deploying are two separate steps.
Alternatives
Webhook on every publish, Scheduled rebuilds
Contact form without a backend
Context
The contact form is the only dynamic feature on the site.
Decision
Submit to a third-party form endpoint straight from the browser.
Tradeoff
It depends on an external service and its limits.
Alternatives
Serverless function, Plain mailto link
Typed GROQ queries
Context
Changes to the schema could silently break the frontend.
Decision
Generate TypeScript types from the schema and queries with Sanity TypeGen.
Tradeoff
There's an extra generation step after every schema change.
Alternatives
Hand-written types, GraphQL with codegen
