DEV Community

Cover image for How I Built an AI Tattoo Generator with Next.js, Cloudflare, Google OAuth, and PayPal
spoon yang
spoon yang

Posted on

How I Built an AI Tattoo Generator with Next.js, Cloudflare, Google OAuth, and PayPal

How I Built an AI Tattoo Generator with Next.js, Cloudflare, Google OAuth, and PayPal

I recently shipped BodyInk.art, an AI tattoo generator that helps users explore tattoo concepts before going to a studio.

In this post, I want to share the engineering side: what worked, what broke in production, and what I changed to make the app stable.

The Product Goal

Tattoo ideation is often slow:

  • users collect references from many places
  • style direction is unclear early on
  • multiple revision rounds happen before a final direction

I wanted a workflow where users can type an idea, generate concepts quickly, and download results for discussion with tattoo artists.

Stack Choice

I used:

  • Next.js App Router for pages and API routes
  • Cloudflare Pages for deployment
  • Google OAuth (NextAuth) for sign-in
  • PayPal for pay-per-generation
  • an AI image backend for tattoo image generation

This stack gave me fast iteration and global delivery, but it also exposed some runtime differences I had to handle.

The First Real Production Bug

After deployment, image generation failed with:

Cannot read properties of null (reading 'has')

At first it looked like a random null bug, but the root cause was runtime incompatibility. A dependency path assumed Node-like behavior, while the deployed environment executed in an Edge-like context.

What fixed it

I replaced the problematic SDK-dependent path with a simpler fetch-based implementation and removed Node-only assumptions from the generation flow.

Result:

  • no more random null access in the hot path
  • easier debugging because request/response behavior became explicit

Base64 and Edge Runtime Gotchas

Another source of 500 errors was image encoding. The naive conversion strategy caused performance and reliability issues under constrained runtime conditions.

I switched to chunked Uint8Array processing instead of relying on heavier Node-oriented patterns. This reduced pressure on runtime limits and made generation responses stable.

If you process image buffers on serverless/edge platforms, don’t assume desktop Node behavior will hold.

Adding Google OAuth with NextAuth

I integrated Google sign-in using NextAuth with callback route:

/api/auth/callback/google

Implementation notes:

  • keep OAuth credentials in environment variables
  • define the correct NEXTAUTH_URL per environment
  • verify provider callback settings match your production domain exactly

The biggest practical issue is usually config mismatch, not code.

Adding PayPal: Sandbox First, Then Live

The business rule is simple: $1 per generation.

I implemented two endpoints:

  • create order
  • capture payment

And I kept env-driven mode switching so I could test safely in Sandbox and then move to Live.

Important details:

  • lock amount/currency on the server side
  • never trust client-only payment state
  • return clear failure messages to avoid silent checkout errors

SEO and Analytics

After core flows worked, I optimized discoverability:

  • improved page-level metadata
  • added sitemap and robots
  • integrated Google Analytics globally

For analytics in Next.js App Router, a framework-aligned integration keeps scripts cleaner and avoids layout-level duplication.

Lessons Learned

  1. Runtime differences matter more than local success.
  2. Keep payment logic server-authoritative.
  3. Integrations fail more from misconfiguration than code defects.
  4. Production debugging gets easier when dependencies are minimal in critical paths.

What I’d Improve Next

  • better prompt guidance for first-time users
  • stronger style consistency controls
  • smarter retry/fallback strategy for generation failures
  • clearer pricing and credit UX

Final Thoughts

Shipping AI features is not just model quality. It is mostly engineering reliability:

  • predictable runtime behavior
  • robust payment flow
  • traceable errors
  • fast iteration loop

If you’re building a similar AI product on Next.js + Cloudflare, I hope this saves you a few painful nights.

If you want, I can share a follow-up post with concrete route structure, env templates, and a deployment checklist.

Top comments (0)