PixelPets: launch report

An AI pet-raising browser game. Generate a pet, feed it, battle friends, climb the leaderboard.
URLpixelpets.app
REPOgithub.com/maya-dev/pixelpets
STACKLovable · React/Vite · Supabase
CHECKEDOct 14, 2026 · 41 min
62/100 LAUNCH
SCORE

00 TL;DR

Don't launch yet. You're about two hours of prompting away. PixelPets is fun, fast to sign up for, and mostly solid. But there are two problems that could cost you real money and your players' trust: your OpenAI key is visible to anyone, and your users table (emails included) can be read by anyone with your public Supabase URL.

Fix the two criticals today, knock out the four warnings before you post it anywhere, and treat the heads-ups as polish. Every finding below has a prompt you can paste straight into Lovable.

2Critical
4Warning
4Heads-up
14Passed

01 What the severity levels mean

CRITICAL
Can cost you money, leak user data, or take the app down. Fix before anyone else sees it.
WARNING
Real users will hit this and some will leave. Fix before you launch publicly.
HEADS-UP
Polish and basics. Won't break anything, but makes you look more legit.

02 Score by area

🔐 Secrets & security
30
🔗 Broken pages & links
70
⚡ Performance
55
🧱 Missing basics
68
🚀 Deploy
85

03 Fix in this order

  1. Rotate your OpenAI key and move the call server-side VS-01 · ~20 min
  2. Turn on Row Level Security for users and pets VS-02 · ~15 min
  3. Fix the /leaderboard crash VS-03 · ~10 min
  4. Add an error screen so failures aren't a blank page VS-04 · ~10 min
  5. Shrink the hero image VS-05 · ~5 min
  6. Turn off public source maps VS-06 · ~2 min
  7. Heads-ups: privacy page, meta/OG tags, mobile leaderboard, www redirect VS-07–10 · ~30 min

04 Findings

VS-01

Your OpenAI API key is public

CRITICALSECRETS~20 MIN
What's wrong
Your OpenAI key (sk-proj-Xr7…a9Qx) is baked into the JavaScript every visitor downloads. It's in there because it's stored as VITE_OPENAI_API_KEY, and anything starting with VITE_ gets shipped to the browser.
Where
/assets/index-4f2a91c.js, line 1, char 48,211. Also in src/lib/generatePet.ts.
Why it matters
Bots scrape for these constantly. Someone can copy it in 10 seconds and spend your OpenAI credits until you hit your limit. People have woken up to four-figure bills.
Do this first
Rotate the key now in the OpenAI dashboard (API keys → revoke → create new). The old one is burned even after you fix the code.
Fix prompt · Lovablecopy & paste
Move all OpenAI API calls out of the frontend. Create a Supabase Edge Function called "generate-pet" that:
1. Reads OPENAI_API_KEY from Supabase secrets (not from any VITE_ variable).
2. Requires the caller to be logged in (verify the Supabase auth JWT) and returns 401 otherwise.
3. Accepts { petName, vibe } in the request body, calls the OpenAI API server-side, and returns only the generated pet data.
Update src/lib/generatePet.ts to call this edge function with supabase.functions.invoke("generate-pet") instead of calling OpenAI directly. Then delete VITE_OPENAI_API_KEY from all .env files and from the code, and confirm no string starting with "sk-" remains anywhere in the src folder.
VS-02

Anyone can read every player's email address

CRITICALSECURITY · DATABASE~15 MIN
What's wrong
Row Level Security (RLS) is off on your users and pets tables. Using only the public anon key from your site, we pulled all 312 rows of users, including emails, and could have edited anyone's pet stats.
Where
Supabase project xyzpets, tables public.users, public.pets.
Why it matters
That's a data leak of your players' personal info, and anyone can cheat the leaderboard by editing rows directly. Supabase's anon key is meant to be public, but only if RLS is on.
Fix prompt · Lovablecopy & paste
Enable Row Level Security on the Supabase tables "users" and "pets" and add these policies:
- users: a logged-in user can SELECT and UPDATE only their own row (auth.uid() = id). No one can SELECT other users' emails.
- pets: anyone can SELECT name, level, owner_display_name and avatar_url (for the public leaderboard), but only the owner (auth.uid() = owner_id) can INSERT, UPDATE or DELETE their pets.
Create a database view "leaderboard" that exposes only pet name, level, xp and owner display name, and use it on the leaderboard page instead of querying users directly. Show me the SQL migration before applying it.
VS-03

The leaderboard page crashes (500 error)

WARNINGBROKEN PAGES~10 MIN
What's wrong
/leaderboard fails for everyone. The console says TypeError: Cannot read properties of null (reading 'display_name'). One pet has an owner that was deleted, and the code assumes every pet has an owner.
Where
src/pages/Leaderboard.tsx, line 38: pet.owner.display_name
Why it matters
It's linked from your homepage and your nav. It's the first thing a competitive player clicks.
Fix prompt · Lovablecopy & paste
The /leaderboard page crashes with "Cannot read properties of null (reading 'display_name')" because some pets have no owner. In src/pages/Leaderboard.tsx, use optional chaining and show "Unknown trainer" when pet.owner is null. Also filter out pets with a null owner_id in the query, and add an ON DELETE CASCADE to the pets.owner_id foreign key so orphaned pets can't happen again. Add a loading state and an "Couldn't load the leaderboard, try again" message if the query fails.
VS-04

When something fails, players get a blank white screen

WARNINGMISSING BASICS · ERROR HANDLING~10 MIN
What's wrong
There's no error boundary. If pet generation fails (we simulated an API timeout), the whole app unmounts and shows a white page with no message and no way back.
Where
src/App.tsx, plus the "Hatch my pet" button in src/components/HatchButton.tsx.
Why it matters
APIs time out. Users assume your app is dead and close the tab. A friendly error with a retry button keeps them.
Fix prompt · Lovablecopy & paste
Add a React error boundary around the routes in src/App.tsx that shows a friendly on-brand screen ("Your pet tripped over a cable 🙀") with a "Try again" button that reloads the current route and a "Back home" link. In HatchButton.tsx, wrap the generate call in try/catch, show a toast with the error and a retry button, and disable the button while a request is in flight so it can't be double-clicked. Add a 20-second timeout to the request.
VS-05

Your homepage takes 6.1 seconds to appear on phones

WARNINGPERFORMANCE~5 MIN
What's wrong
Largest Contentful Paint is 6.1s on a mid-range phone over 4G (target: under 2.5s). The main culprit is hero.png at 4.8 MB (2880×1800). Your JS bundle is 1.1 MB, mostly because all 40 pet sprite sheets are imported up front.
Where
/public/hero.png, src/assets/sprites/index.ts
Why it matters
Roughly half of mobile visitors leave if a page takes longer than 3 seconds. Launch-day traffic from X and Reddit is mostly mobile.
Fix prompt · Lovablecopy & paste
Speed up the homepage on mobile:
1. Convert /public/hero.png to WebP, max 1600px wide and under 200 KB, and serve a 800px version to small screens using srcset. Set explicit width and height, plus fetchpriority="high" on the hero image.
2. Add loading="lazy" to every other image.
3. In src/assets/sprites/index.ts, stop importing all sprite sheets up front. Lazy-load each pet's sprite only when that pet is shown, using dynamic import().
4. Lazy-load the /battle and /leaderboard routes with React.lazy and Suspense.
VS-06

Your full source code is downloadable in production

WARNINGDEPLOY~2 MIN
What's wrong
Source maps are being deployed. /assets/index-4f2a91c.js.map is public and rebuilds your original, readable src/ folder, comments included.
Why it matters
It makes finding bugs and secrets (see VS-01) trivially easy for anyone poking around, and hands your game logic to copycats.
Fix prompt · Lovablecopy & paste
In vite.config.ts, set build.sourcemap to false for production builds (keep it on for development). Then rebuild and confirm that no .js.map files are produced in the dist/assets folder.
VS-07

No privacy policy, but you collect emails and use Google login

HEADS-UPMISSING BASICS~10 MIN
What's wrong
No /privacy or /terms page, and nothing linked in the footer. You collect emails and use Google sign-in, and Google requires a privacy policy URL on your OAuth consent screen before it's verified for public use.
Why it matters
It's often legally required, Google can block your login, and players trust apps more when the page exists.
Fix prompt · Lovablecopy & paste
Create /privacy and /terms pages in plain, friendly English for a small browser game called PixelPets. The privacy page should cover: we collect email and display name via Google sign-in, we store pets and game stats in Supabase, pet names and prompts are sent to OpenAI to generate pets, we don't sell data, and how to request account deletion by email at [YOUR EMAIL]. Link both pages in the site footer. Add a note at the top to have the text reviewed before relying on it.
VS-08

Shared links show up as "Vite + React + TS" with no preview

HEADS-UPMETA / SEO~5 MIN
What's wrong
Your page title is still the template default Vite + React + TS. There's no meta description, no og:image and no Twitter card tags, and the favicon is the Vite logo.
Why it matters
When you post your launch on X, Discord or Reddit, the link preview is a blank grey box. That costs you clicks right when you need them.
Fix prompt · Lovablecopy & paste
In index.html set the title to "PixelPets: raise and battle AI-generated pets" and add a meta description (under 155 characters). Add Open Graph and Twitter card tags (og:title, og:description, og:image, og:url, twitter:card="summary_large_image"). Create a 1200x630 og-image.png in /public showing the logo and three pets. Replace the Vite favicon with a PixelPets favicon, plus an apple-touch-icon.
VS-09

Leaderboard spills off the screen on phones

HEADS-UPMOBILE~5 MIN
What's wrong
At 375px wide (iPhone SE/mini), the leaderboard table is 540px wide and the whole page scrolls sideways. The "Feed" and "Play" buttons on the pet screen are 28px tall, below the 44px minimum for comfy tapping.
Why it matters
Sideways scrolling feels broken, and small buttons cause mis-taps in a game where tapping is the whole point.
Fix prompt · Lovablecopy & paste
Make the leaderboard mobile friendly: below 640px, switch the table to a stacked card layout (rank, pet avatar, pet name, level, trainer) with no horizontal scrolling. On the pet screen, make the Feed, Play and Battle buttons at least 44px tall with at least 8px between them. Check that no page scrolls horizontally at 360px width.
VS-10

www.pixelpets.app shows a security warning

HEADS-UPDEPLOY~5 MIN
What's wrong
pixelpets.app works fine, but www.pixelpets.app points at your host without an SSL certificate, so browsers show "Your connection is not private."
Why it matters
Lots of people type www out of habit. A scary warning makes them think they've been hacked.
Fix prompt · any tool / hosting dashboardcopy & paste
I host pixelpets.app on [Netlify / Vercel / Lovable hosting]. Walk me step by step through adding www.pixelpets.app as a domain alias with a valid SSL certificate and a permanent 301 redirect from www to the apex domain pixelpets.app. Tell me exactly which DNS record to add at my registrar.

05 What's already good (14 passed)

HTTPS with a valid cert on pixelpets.app
HTTP redirects to HTTPS
.env is in .gitignore
No secrets found in git history
Supabase service-role key not exposed
Mobile viewport meta tag present
Custom 404 page
All 23 pages reachable (except /leaderboard)
0 broken external links
Gzip/Brotli compression enabled
Static assets cached with hashed filenames
Google login redirect works in prod
No mixed-content warnings
All prod env vars present
VibeSweep · vibesweep.dev · Report #VS-2026-0142 (example) · Checked Oct 14, 2026 An automated launch check to secure your peace of mind.