> sample_audit --target nyxxi.io

Sample audit: nyxxi.io

A real report, published with permission. Nyxxi is an AI character app by Twisted Flame Productions. Audited Fri Oct 16, 2026 using headless Chrome at desktop (1280px) and phone (390px) widths, plus Lighthouse 12 in mobile and desktop modes. No real data was submitted.

Status: 8 of 10 issues fully fixed, 2 partly fixed. Fixes shipped Oct 17, 2026, the day after the audit. We re-checked the live site on Oct 18 (headless Chrome + Lighthouse): Accessibility, Best Practices and SEO all score 100. Still open: a share preview image (#4) and mobile animation work (#10). This is exactly what a $29 audit delivers: the top 10 issues ranked by user impact, each with a fix prompt you can paste into Cursor or Lovable.

Top 10 issues, ranked by user impact

1. Social icons link to generic homepages

HighFixed

What: The footer's GitHub, X, Discord and YouTube icons pointed to github.com, x.com, discord.com and youtube.com, not to Nyxxi's own accounts.

Repro: Scroll to the footer and tap the X icon. It opened x.com's homepage.

In the landing page footer social links array (GitHub, X, Discord, YouTube), replace the placeholder homepage URLs with Nyxxi's real profile URLs. Remove any icon we don't have an account for. Keep target="_blank" and add rel="noopener noreferrer".

2. Paid plans couldn't be bought

High (revenue)Fixed

What: The checkout link map was empty, so "Start Studio" and "Upgrade to Studio" only led to a waitlist, and "Talk to us" (Agency, $79/mo) had no contact route. The price cards and "Upgrade" wording overpromised.

Repro: Open the app, click "Upgrade to Studio". You landed on the homepage instead of a checkout.

Set the Studio monthly/yearly and Agency price links to real Stripe Payment Links so "Start Studio" and "Upgrade to Studio" open checkout. Until those exist, relabel the buttons "Join Studio waitlist", mark the price cards "Coming soon", and make "Talk to us" a mailto: link or contact form.

3. Fixed header overlapped content on mobile

MediumFixed

What: At 390px, the big "OPEN NYXXI" button scrolled under the transparent fixed header and sat on top of the header's own button and logo.

Give the fixed header a solid or blurred background (e.g. background: rgba(5,5,10,.85); backdrop-filter: blur(8px)) and a z-index above page content, and add scroll-margin-top to sections so content never renders under it on mobile.

4. Missing share image and tags (og:image, Twitter card, canonical)

MediumPartly fixed

What: Only og:title, og:description and og:type were set, so links shared on X, Discord or iMessage showed no preview image. No canonical link; the app page had no OG tags at all.

Add to the index.html head: og:image (1200x630 PNG), og:url, og:site_name, twitter:card=summary_large_image, twitter:image, and a canonical link. Add noindex to the app page.

Re-check Oct 18: canonical, og:url, og:site_name and Twitter tags are live and the app page is noindexed. No og:image yet, so shared links still show no preview image.

5. robots.txt and sitemap.xml returned the homepage

Medium (SEO)Fixed

What: Both files returned the landing page's HTML. Lighthouse reported robots.txt as invalid (SEO score 91).

Add public/robots.txt (User-agent: * / Allow: / / Sitemap: ...) and public/sitemap.xml listing / so Cloudflare Pages serves them as static files instead of the SPA fallback.

6. Unknown URLs returned the homepage instead of a 404

Low–MediumFixed

What: Mistyped URLs returned 200 and the landing page, so users got no "not found" message and search engines could index junk URLs.

Add a public/404.html page with a link back home so Cloudflare Pages returns a real 404 for unknown paths, keeping SPA routing only under /app/* via a _redirects rule.

7. App form fields had no labels

Medium (accessibility)Fixed

What: The search box, character Name input, file input and Look textarea had no programmatic label, so screen readers announced them only as "edit text". The theme toggle's name was just an emoji.

Connect each visible label ("Name", "Character sheet", "Look") to its input with htmlFor/id, add aria-label="Search" to the search input, and give the theme toggle aria-label="Switch to light theme" (update it dynamically).

8. Low-contrast text

Low–Medium (accessibility)Fixed

What: Lighthouse flagged tag labels (3.65:1), grey text (3.69:1) and gold text (3.36:1). WCAG AA needs 4.5:1 for small text.

Raise contrast for small text: lighten the tag color to about #9d93ee, the muted grey to about #a29db5, and the gold to about #d4a14e (verify each at ≥4.5:1 against the background).

9. Broken heading structure

Low (accessibility + SEO)Fixed

What: The H1 read as single letters "N Y X X I", several headings were empty, and heading levels skipped.

Make the H1 a single readable text node (aria-label="Nyxxi" with decorative spans aria-hidden), give every H2 real text or demote decorative ones, and fix heading levels so they don't skip.

10. Mobile main-thread work; missing CSP and clickjacking headers

LowPartly fixed

What: Mobile Lighthouse performance was 87 (FCP 2.1s, Speed Index 4.5s, TBT 280ms) with about 23 KiB of unused animation JS; desktop scored 100. No Content-Security-Policy or frame-ancestors header. The waitlist form had no spam protection.

Add a _headers file with a Content-Security-Policy (including frame-ancestors 'none') and X-Frame-Options: DENY. Lazy-load scroll animations after first paint and respect prefers-reduced-motion. Reject duplicate/malformed waitlist emails and add a honeypot field.

Re-check Oct 18: Content-Security-Policy (with frame-ancestors 'none') and X-Frame-Options: DENY are live. Mobile Lighthouse performance is now 91, but main-thread blocking (about 340ms) remains, and the animation lazy-loading hasn't shipped.

What was already working well

Want this for your app?

Top 10 issues + fix prompts within 24 hours.

VibeCheck Daily

One vibe-coding security tip a day. Free, unsubscribe anytime.

We only use your email for VibeCheck Daily. Unsubscribe anytime.