/ recent work / antipretty

AntiPretty

Alt-modeling gallery and community relaunch — fifteen years of shoots on WordPress, rebuilt in days on Payload with bulk gallery import, member profiles, DMs, casting calls, and Miss AntiPretty.

AntiPretty — preview
Year
2026
Role
Solo build + ops
Status
live
Stack
  • Next.js 16
  • Payload CMS 3
  • Supabase Postgres
  • Bunny CDN
  • Netlify
  • Anthropic

Alt-modeling agency and creative community — “We Like Them Weird.” The brand has been live since 2015: portfolios, editorial cadence, unconventional beauty without airbrushing. The WordPress stack worked until it didn’t — plugins, hosting quirks, the mental tax of wp-admin when you only wanted to fix one gallery grid. We scrapped to a blank Payload template and counted hours, not sprints.

The problem

Fifteen years of galleries, model rosters, and editorial voice lived on a custom WordPress theme. It accumulated. Every social feature — member accounts, DMs, casting calls, contest voting — would’ve meant another plugin stack and another round of theme surgery.

The goal wasn’t a fresher admin skin. It was ownership: typed collections, CDN URLs we control, a front-end that matches the brand instead of fighting the theme. And we needed the archive back — not lorem placeholders, the actual weird captions.

The approach

Relaunch-first, social second. Phase 1: Concept-B front-end (Punk Zine / Riso-Collage — newsprint, halftone, taped polaroids, sticker marquees), content model, importers, SEO. Phase 2 shipped in the same weekend: Payload auth, profiles, follow graph, on-site DMs, casting calls, Miss AntiPretty.

Storage-agnostic images. Series accept uploaded Media or external URLs so content renders before Bunny is wired. Importers pull WordPress REST and legacy S3 buckets; resumable batches with honest logging when a gallery fetch stalls mid-run.

Adult-tolerant infra. Image bytes live on Bunny.net — Cloudinary bans nudity, Netlify only serves markup referencing CDN URLs. Supabase Postgres through the transaction pooler (:6543) for serverless; Sharp on linux x64 for Netlify builds.

What we built

  • Galleries & roster — filterable index, series detail with masonry frames and keyboard/swipe lightbox, model profiles with credits and custom URLs, tag taxonomy, site search.
  • Bulk migration — 29 WordPress galleries, 1,247 photos; S3→Bunny→Series pipeline; archive review panel with EXIF regrouping; real copy backfilled for dozens of recovered shoots.
  • Concept-B UI — age gate, masthead/footer, hero polaroid collage, sticker marquee, manifesto scrap, branded 404, dynamic OG share cards, JSON-LD and canonicals.
  • Members & social — auth collection, profile editor, claim flows, follow/unfollow, DMs with read receipts and block list, comments on shoots and profiles.
  • Casting & contests — casting calls with applications inbox; Miss AntiPretty entries and voting; Submit Your Work / join page.
  • AI enrichment — Claude-assisted SEO titles, social captions, tags, and alt text (human-reviewed in Payload before publish).
  • Admin polish — image-grid preview on Series edit, photo credits, soft filters, newsletter capture, contact page.

Trade-offs

Deploy stays manual — netlify deploy --prod --build with a project-id guard. GitHub→Netlify CD isn’t wired yet; this site doesn’t need to burn build minutes on every copy tweak.

Editorial rhythm is still finding its legs on the new stack — same as FuhNNY after Webflow. Galleries ship while the voice catches up.

Import jobs need retry and EXIF fallbacks because “undated” buckets are where content goes to die. Serverless Postgres pools cap connections — fine until a batch job and a cold admin session collide.

Results

Live at antipretty.com. Netlify on manual deploy, Supabase Micro in us-east-2, media on antipretty.b-cdn.net. The loop we care about: import a shoot, enrich copy in admin, publish — member claims profile, photographer posts a casting call, fan votes in Miss AntiPretty. Same brand posture, no PHP.

What’s ongoing

Domain cutover polish, Lighthouse pass on gallery LCP, GitHub→Netlify CD wiring, ongoing archive batches from legacy S3. Deploy when Adam says go.

Recent shipping (May–June 2026)

  • May 31 → June 1 — blank Payload scaffold, Concept-B front-end, Bunny CDN wired, WordPress + S3 importers, 29 galleries migrated with resumable fetch.
  • Phase 3 Wave 1 — member auth, profile editor, claim flows, discovery pages, password-reset email via Workspace SMTP / Resend fallback.
  • Social wave — follows, on-site DMs, read receipts, block/unblock, comments on shoots and profiles.
  • Casting + contest — casting calls with applications; Miss AntiPretty entries and voting with cascade deletes.
  • SEO + admin — JSON-LD, canonical domain, richer sitemap; image-grid preview on Series edit view.