Spencer Grey Art
Visit the live siteOverview
Spencer Grey is a Seattle painter whose work draws on a cosmic, spiritual sensibility. The brief was a full artist portfolio and print store that felt nothing like a template.
Framework
- Next.js 15 (App Router)
- React
- TypeScript
Data
- Neon (serverless Postgres)
- Cloudflare R2
Auth
- iron-session (cookie-based)
Commerce
- Stripe
Type
- Cardinal Fruit
- Suisse Intl
Hosting
- Vercel
The Problem
The default options for an artist site — a generic portfolio template or an Etsy-style craft marketplace — would have flattened the work.
Key challenges included:
- Needed to avoid the plain-grid-plus-headshot look of most artist portfolio templates
- Needed to avoid reading as a craft marketplace
- Wanted a "raw, intimate, cinematic" studio-visit feel instead
The Solution
A custom Next.js build instead of a page builder, with a full commerce layer underneath a deliberately quiet design.
Store & Admin
Edition tracking, Stripe checkout, and a full custom admin CMS for managing artwork, collections, and orders — built rather than bolted onto a template.
Design System
A dual-typeface fluid type system, full-bleed dark imagery, and near-zero copy — five stated design principles: the work commands the frame, intimacy over polish, black as gallery wall, earn the collector's patience, and every word of copy earns its place.
Voice
Alt text and copy written in Spencer's own voice — specific material descriptions, not generic "artwork image" filler.
Under the Hood
Migrating off Supabase mid-project
The store originally ran on Supabase for all three of database, auth, and file storage. That is convenient until the subscription is the largest line item on a small artist store. It moved to Neon for Postgres, iron-session for auth, and Cloudflare R2 for images, which removed the recurring cost entirely. The migration ran as two scripts: one to build the schema, one to move the data and re-upload every image into R2 under its own prefix. Three collections, eight artworks, ten content rows, eleven orders, and a blog post came across without downtime.
Auth without an identity provider
There is exactly one admin. Standing up a full identity provider for one person is the kind of decision that quietly adds a dependency, a bill, and an outage you do not control. Admin auth is an encrypted iron-session cookie instead, which is a few dozen lines and no third party in the login path.
Design rules that decide arguments in advance
The build runs on five written principles: the work commands the frame, intimacy over polish, black as gallery wall, earn the collector's patience, and every word of copy earns its place. They exist so layout questions have an answer before anyone debates them. In practice that produced a full-bleed 16/7 hero with the call to action tucked bottom-left so it never sits on top of the painting, a cream and near-black palette instead of pure white, and near-zero body copy anywhere near the work.
Alt text as writing, not compliance
Every image describes its real materials and subject in the artist's own register. The default is a filename or the phrase artwork image. That is an accessibility requirement and a search signal at the same time, and it is the difference between a screen reader describing a painting and announcing a placeholder.
The Outcome
Live at spencergreyart.com, running on Next.js, Neon, and Cloudflare R2 after a mid-project infrastructure migration off Supabase.



