← All work

Aaronis Tattoo

Written byWill Pei Yuan

Aaron Is is a Tampa-based tattoo artist and Ink Master (Season 5) alum who guests at conventions and shops around the country. The site is a single-artist brand page built around that credibility: a bio, a travel schedule that counts down to the next convention, media coverage, and three ways to reach him — email, an Instagram DM, or a written inquiry — with no booking form or shop in between.

Role —
Design and build, end to end, traded for tattoo work. The concept and the visual direction were mine, drawn from the feel I picked up working with Aaron.
Timeline —
December 2025 — ongoing. First version December 12, 2025, refined through January; in August 2026 the travel schedule moved to his Instagram bio.
Stack —
Next.js, React, Tailwind CSS, Radix UI, Neon Postgres, JotForm, Instagram via RapidAPI, Vitest, Vercel, Schema.org structured data
Visit aaronistattoo.com ↗

The problem

This one started in his chair: I was a client of Aaron's for his style of tattooing, and we became friends. Somewhere in that, I offered a trade — my work for his. He had a following and no website. His press, his TV appearance and his videos were scattered across newspapers, YouTube and Paramount+, and Instagram was the whole business, including booking, which ran through DMs. Two pain points came out of that conversation. Booking: getting a new client to fill out the details he needs and pay a deposit, without a back-and-forth in his messages. And presentation: a professional place to represent his work, beyond a grid on someone else's app. The site is the answer to both, built so he can keep running everything else from Instagram.

What I built

The site is a small set of routes off one nav: Work (home), About, Travel, Media, Shop, FAQ, Contact. Home leads with a full-bleed hero photo, a "next up" banner naming the closest upcoming convention and a live day-count, a "recent work" section that hands off to @aaronistattoo rather than holding its own image grid, and a travel strip listing the next few stops. /services, /gallery, /portfolio and /artists are not routes — they 404.

The About page carries the résumé: Ink Master Season 5, a guest spot at Trip Ink Tattoo in Las Vegas, convention dates through early next year, and an affiliate partnership with @xactbodyart offering a 20%-off code tied to his name. Media lists nine placements — the two 2014 newspaper pieces about his Ink Master run, six YouTube videos, and a Paramount+ link — each with a date and a one-line description. FAQ lists six questions (booking, deposits, cover-ups, references, prep, travel) as headings; the site does not expose their answers in the page markup I could read without running the client JS.

Contact offers three ways in: an email link, an Instagram DM link, and an embedded JotForm booking inquiry that asks for placement, size, references, timeline and budget. Booking and Travel hand off to the same channels. Shop exists as a route but is a "Coming Soon" placeholder with no products.

Design decisions

How it looks and moves, and why.

Black, one pink, and inscription capitals

The palette is near-black greys with a single magenta-pink accent, and the display face is Cinzel — capitals cut after Roman inscriptions. The pink is the only colour in the theme — the accent and the focus ring — so everything else steps out of the way of the photographs. Nobody handed over a brand. The direction was mine, built on the feel I picked up from working with Aaron rather than on a studio template.

The photo first, the name over it

Home opens on a full-bleed photograph behind a 30% black overlay, so the name and the Ink Master credit sit over the work rather than above it. The next convention and its day count sit right under it, so the first screen answers who he is and where he will be.

Decisions worth explaining

The engineering, for anyone who wants it.

The schedule lives in his Instagram bio, so the site reads it

Aaron keeps his dates in his Instagram bio — “Aug 21-23 Tampa”, “Aug 28-30 Colorado”, “Sept 4-6 Amsterdam” — and that is the one place he updates. The first version of the site kept its own hand-entered schedule, and by August 2026 the two had drifted: the site said his next stop was Tampa in November on a day he was in Tampa, with Colorado and Amsterdam to follow. Rather than ask him to update two places, the site now fetches the bio and parses it. A bio is capped at 150 characters, though, and his was at 145, so it cannot hold the whole year. The answer is a merge: shows entered on the site — like his Tampa home convention, pinned in a banner at the top of the travel page — are combined with the stops parsed from the bio, matched by city and month and year, and the bio wins wherever the two disagree. The site’s entries also add what a bio line cannot carry: a venue, a ticket link, a banner. He edits his bio, and the homepage and the travel page follow.

A parser that cannot lose his words

Bio text is written for people, not machines, so the parser is a pure function with no network or database in it, covered by Vitest cases for the date shapes he actually uses. When a line cannot be parsed, his exact wording still reaches the page rather than disappearing. When Instagram cannot be reached at all, the fetch returns nothing instead of throwing and the site’s own schedule stands in, so the travel page is never blank; a one-hour cache keeps the API calls down.

Structured data ties the domain to the person

The site publishes Schema.org Person data: job title, an alumniOf link to Ink Master as a TVSeries, sameAs links to his Instagram and Facebook, a knowsAbout list (geometric tattoo design, black and gray, tattoo conventions), and areaServed covering Tampa plus the cities on his travel circuit. That is the same pattern search engines use to connect a small site to an artist they may already have other signals about.

An AI assistant, built and then left off

Yumi, a JotForm AI agent, could take the same booking inquiry as a conversation, and it was built. It also cut against Aaron’s ethos on AI: he wanted a more human response. That was the right call for him, so the plain form is what visitors get, and Yumi sits behind a ?yumi switch on the contact page rather than in front of anyone.

Booking runs on a form service, not a form of its own

The booking inquiry is a JotForm embed, and the Yumi assistant is a JotForm AI agent, rather than fields posting to the site’s own backend. JotForm was easy to stand up, and it connects to payment methods, which is what the deposit needs. Building the same thing into the site — a form, a payment processor, the webhooks between them — would have been more time and more to maintain than Aaron needed. The form solves the booking problem; the site’s job is to get people to it.

The stack, and why

Each layer, what it runs on, and what it was picked over.

Framework

Next.js App Router

A handful of content pages that render fast, plus server routes for the Instagram and analytics calls so no API key ever reaches the browser.

UI

Tailwind CSS and Radix primitives

Theme tokens for the black-and-pink palette, and accessible building blocks from Radix for the FAQ accordion and the toasts rather than hand-rolled ones.

Instagram data

An Instagram API via RapidAPI, cached for an hour

The profile bio drives the travel schedule, so the site needs it server-side. Every call goes through one fetch helper with a one-hour in-memory cache, and a failed call returns nothing rather than throwing, so an Instagram outage falls back to the site’s own schedule instead of breaking the page.

Schedule parsing

A pure TypeScript parser, tested with Vitest

The only module with real logic has no I/O in it, so every date format in his bio can be pinned by a test and run in milliseconds.

Booking

JotForm, plus a JotForm AI agent

Easy to stand up, and it connects to payment methods for the deposit. A form and payment flow of the site’s own would have been more build and more upkeep than the job called for.

Analytics

Vercel Analytics, plus its own events in Neon Postgres

Every tracked event goes to Vercel Analytics and to an events table of the site’s own, read by a dashboard at /analytics. A failure to record never breaks the page. The second store is a preference rather than a requirement.

Hosting

Vercel

Deploys from git, with the database URL and API keys kept in the project’s environment.

← All work