All 162 checks
Every check VibeCheck runs against your app. Filterable by category and severity.
162 checks
Login redirect loop after OAuth
Detects infinite redirect loops that occur after OAuth login completion.
Expired JWT not handled — blank screen
Navigates to protected routes and checks for blank/white screens indicating unhandled token expiry.
Protected routes accessible via direct URL
Attempts to navigate to common dashboard paths without auth.
OAuth callback URL mismatch
Checks network responses for OAuth redirect_uri mismatch errors.
Supabase RLS missing — cross-user data read
Checks if Supabase anon key is exposed without evidence of RLS policies.
Admin routes only hidden, not protected
Checks if admin UI is merely hidden vs. actually gated server-side.
Stripe test keys in production
Detects sk_test_ or pk_test_ keys exposed in page source or network requests.
Missing HTTPS on payment pages
Verifies payment pages are served over HTTPS.
Supabase anon key in client with no visible RLS
Checks for exposed Supabase anon key alongside direct table access patterns.
API returns sensitive fields
Checks common API endpoints for password, token, or secret fields in responses.
Environment variables visible in page source
Checks for NEXT_PUBLIC_ var leaks or other env var patterns in client source.
API endpoints accessible without auth headers
Makes unauthenticated requests to common API routes.
Mobile viewport meta tag missing or misconfigured
Checks for correct viewport meta tag configuration.
HTTP accessible — no HTTPS redirect
Checks if HTTP version of the URL redirects to HTTPS.
Sensitive env vars in client bundle
Scans JavaScript bundles for private key patterns.
Admin UI role-gated only on frontend
Checks if admin functionality has server-side guards.
OpenAI key exposed client-side
Scans page source and JS bundles for OpenAI secret key patterns.
Anthropic key exposed client-side
Scans page source and JS bundles for Anthropic secret key patterns.
Other AI provider keys exposed client-side
Scans for Replicate, Groq, and Google AI key patterns in client code.
JavaScript sourcemaps publicly accessible
Checks whether .map files for JS bundles are publicly reachable.
Social login fails silently
Checks if OAuth provider buttons exist and whether failure states show error messages.
Session not invalidated on logout
Checks for logout functionality and verifies it properly clears session state.
Password reset link reusable
Checks if password reset tokens are single-use.
No rate limiting on login
Checks response headers for rate-limiting signals on the login form.
Magic link works after expiry
Checks if the page handles expired magic link tokens gracefully.
Account deletion does not invalidate sessions
Checks if account deletion UI properly signs out all sessions.
Webhook endpoint not reachable
Makes a HEAD request to /api/webhook/stripe to verify it responds.
Success redirect fires before webhook
Checks if checkout success page grants access immediately without waiting for webhook.
No 3DS/SCA handling detected
Checks if payment flow handles Strong Customer Authentication challenges.
Subscription cancel does not revoke access
Checks cancel flow for immediate vs. period-end access revocation.
Free trial expiry not enforced
Checks if trial state is verified server-side.
No error state when data fails to load
Simulates a slow/failed network and checks for error UI.
No pagination — full table dump to UI
Checks for extremely long lists that suggest unbound database queries.
Form submits to DB with no validation feedback
Checks forms for client-side validation and error messaging.
CORS wildcard header present
Checks API responses for Access-Control-Allow-Origin: * on sensitive routes.
Error responses leak stack traces
Triggers 404 and checks if error response contains stack trace.
File upload endpoint with no size restriction signals
Checks file upload inputs for accept and size validation.
Unhandled promise rejections in console
Checks for unhandledrejection events captured during page load.
Error state missing
Checks for error boundary and error state components.
Form double-submit possible
Checks if form submit buttons are disabled after first click.
Delete action with no confirmation
Checks if delete buttons trigger immediate action without confirmation.
Console errors present on page load
Reports any console errors captured during page load.
Layout breaks at 375px viewport
Resizes viewport to 375px and checks for overflow or layout issues.
Tap targets below 44px
Checks interactive elements for minimum 44px touch target size.
Horizontal scroll present on mobile
Checks for horizontal scrollbar at mobile viewport.
Hover-only interactions present
Checks for CSS hover states that reveal critical UI elements.
No image optimization (large uncompressed images)
Checks for large unoptimized images loaded on the page.
Bundle size above 1MB
Estimates total JavaScript bundle size from network requests.
Time to first byte above 800ms
Measures TTFB using Navigation Timing API.
Largest contentful paint above 2.5s
Measures LCP using PerformanceObserver.
Content-Security-Policy header missing
Checks HTTP response headers for CSP.
CSRF protection absent on forms
Checks for CSRF tokens in forms and headers.
User content served from same origin (XSS risk)
Checks if user-generated content is served from a sandboxed domain.
Mixed content warnings (HTTP on HTTPS page)
Checks for HTTP resources loaded on an HTTPS page.
SPF record not configured for sending domain
Checks DNS TXT records for SPF configuration.
DKIM record not configured
Checks for DKIM DNS records on common email provider selectors.
No unsubscribe mechanism detectable in email flows
Checks settings/notifications pages for unsubscribe options.
Notification links point to localhost or staging
Checks page source for localhost URLs in email/notification templates.
Email confirmation flow broken or unreachable
Checks if signup triggers an email confirmation step.
AI API called directly from browser
Detects network requests made directly to AI provider APIs.
No rate limiting on AI endpoint
Checks if detected AI proxy endpoints return rate-limit headers.
System prompt visible in client bundle
Scans JS bundles for long strings that look like LLM system prompts.
Missing or empty title tag
Checks that the page has a non-empty <title> element.
No privacy policy link
Checks for a link to a privacy policy page.
Email collection without consent notice
Checks if email input forms have an accompanying privacy or consent notice.
Lorem ipsum placeholder text
Checks for lorem ipsum or placeholder text left in the page.
Broken images on page
Checks for img elements that failed to load (naturalWidth === 0).
Broken navigation links
Checks primary nav links for 404 or network errors.
App running in development mode
Detects Next.js development mode, React DevTools hooks, or dev-mode strings.
Debug or test routes accessible
Probes common debug and dev paths for non-404 responses with meaningful content.
Localhost URLs in production
Scans page source for localhost or loopback address references outside code/pre blocks.
Secret environment variables in client bundle
Scans JS bundles for process.env references to secret-sounding variable names.
No error monitoring detected
Checks for Sentry, Bugsnag, LogRocket, Rollbar, Datadog, or Highlight.io.
No analytics detected
Checks for Google Analytics, PostHog, Mixpanel, Plausible, Fathom, and others.
No clear call-to-action above the fold
Checks for a button or CTA link within the first 800px at 1280×800 viewport.
Autoplay video with sound
Checks for <video autoplay> elements missing the muted attribute.
Password reset link expired with no message
Checks password reset flows for expired link handling.
Auth state not synced across tabs
Checks for BroadcastChannel or storage event listeners that sync auth state.
Email verification breaks on different device
Checks if verification links depend on session state (which breaks cross-device).
Duplicate registration via different auth methods
Checks if signup page handles duplicate accounts across email/OAuth.
No feedback during auth loading
Checks if auth forms show loading state during submission.
Failed payment shows generic error only
Checks payment forms for specific error message handling.
Promo field accepts invalid codes silently
Checks if promo/coupon input provides feedback for invalid codes.
Currency mismatch in display vs. charge
Checks if displayed currency matches Stripe locale.
No confirmation email flow detectable
Checks for evidence of email confirmation after purchase.
Checkout session expiry not handled
Checks if expired Stripe Checkout sessions show a proper error.
Payment form accessible without auth
Checks if payment/upgrade page requires authentication.
No loading state during payment submission
Checks if payment submit button shows loading/disabled state.
No soft delete pattern (direct destructive actions)
Checks for hard delete buttons without soft-delete or trash confirmation.
Missing unique constraint signals (duplicate data)
Scans lists for visually identical entries indicating missing DB constraints.
No empty state when collection is empty
Checks for appropriate empty state UI on list/collection pages.
Data loads without loading indicator
Checks if data-heavy sections show a skeleton or spinner.
No rate limiting headers on API responses
Checks for RateLimit or X-RateLimit headers on API responses.
No request timeout handling in UI
Checks if the UI handles slow API responses gracefully.
Sequential API waterfall on page load
Checks network timing for sequential requests that could be parallelized.
Empty state missing
Navigates to collection pages and checks for empty state UI.
Loading state missing
Checks for skeleton screens or spinner elements.
No character limit on text inputs
Checks for maxlength attributes on text inputs and textareas.
Modal does not close on Escape
Checks if modals/dialogs handle the Escape key.
Copy-to-clipboard on non-HTTPS
Checks if clipboard API is used on pages not served over HTTPS.
Back button breaks state
Checks if browser history is managed correctly for multi-step flows.
Font size below 16px on inputs (triggers iOS zoom)
iOS auto-zooms when input font-size is below 16px.
Images overflow on mobile
Checks for images wider than their container at mobile viewport.
Fixed elements hidden behind browser chrome
Checks fixed position elements at bottom of mobile viewport.
No touch-friendly alternatives to drag interactions
Checks for drag-and-drop without touch alternatives.
Layout shift score (CLS) above 0.1 on mobile
Measures Cumulative Layout Shift on mobile viewport.
No lazy loading on below-fold images
Checks if below-fold images have loading="lazy" attribute.
Unminified JS detected
Checks script sizes and content for minification.
No caching headers on static assets
Checks Cache-Control headers on JS, CSS, and image assets.
No skeleton/loading UI on data-dependent sections
Checks for skeleton screens on sections that load async data.
X-Frame-Options header missing
Checks for clickjacking protection headers.
AI provider error messages leaked to client
Probes AI proxy endpoints with a malformed request to check if raw provider errors are exposed.
No AI response timeout visible
Checks if AI proxy calls use AbortController or timeout patterns.
No loading state for AI output
Checks if the app shows visual feedback while waiting for AI responses.
CORS wildcard on AI proxy endpoint
Checks if AI proxy endpoints have an open CORS policy.
Missing meta description
Checks for a non-empty meta description tag.
Missing Open Graph image
Checks for og:image meta tag used by social platforms.
Missing or multiple H1 tags
Checks that exactly one H1 tag exists on the page.
Images missing alt text
Counts images without alt attributes.
No terms of service link
Checks for a link to terms of service or terms of use.
No cookie consent mechanism
Checks for a cookie banner or consent dialog.
No account deletion path for authenticated apps
Checks that apps with auth expose a way for users to delete their account or data.
Age-restricted content with no age gate
Detects age-restricted product categories and checks for an age verification mechanism.
Default framework title in use
Checks if the page still uses the boilerplate title from a starter template.
Placeholder email address
Checks for example.com or placeholder email addresses in visible text.
TODO / placeholder text in content
Checks visible page text for TODO, FIXME, or TBD markers.
Missing custom 404 page
Fetches a non-existent path and checks for a custom 404 response.
Vercel preview URL hardcoded in production
Checks if the production site references temporary *.vercel.app URLs.
Excessive console.log in production bundle
Fetches the main JS bundle and counts console.log occurrences.
Static assets missing cache headers
Checks Cache-Control headers on JS and CSS assets.
No uptime monitoring health endpoint
Checks for a /api/health or /health endpoint as a signal of uptime monitoring.
Hero section too sparse
Counts visible above-fold words (excluding nav) at 1280×800.
No social proof signals
Checks for user counts, star ratings, testimonials, or trust signals.
Page load too slow for launch traffic
Measures DOMContentLoaded time as a Time To Interactive proxy. TTFB is already covered by perf-006.
Remember me does not persist
Checks if "remember me" checkbox exists and session cookies have appropriate expiry.
Timestamps without timezone handling
Checks if timestamps displayed on page are localized.
Infinite scroll with no end state
Checks infinite scroll implementations for a "no more items" state.
Missing Content-Type headers on API responses
Checks API responses for proper Content-Type headers.
API versioning absent
Checks if API routes include versioning (/v1/, /v2/).
Success message timeout too short
Checks if success toasts/alerts auto-dismiss too quickly.
Date format not localized
Checks if dates use hardcoded format instead of locale-aware formatting.
Number format not localized
Checks if large numbers use locale-appropriate formatting.
Toast notifications stack without limit
Checks if toast system has a maximum display count.
Form inputs missing labels
Checks for input elements that lack an associated label.
Potential color contrast issues
Checks for low-opacity or light-colored text that may fail WCAG contrast.
No reply-to address on transactional emails
Checks for reply-to configuration in email setup code.
AI-generated content not labeled
Checks if AI-generated content has any disclosure label or badge.
No AI usage disclosure in privacy policy
Checks if the privacy policy mentions AI or automated processing.
Missing core Open Graph tags
Checks for og:title, og:description, and og:url tags.
robots.txt not found
Fetches /robots.txt and checks for a 200 response.
XML sitemap not found
Checks for /sitemap.xml at the site root.
Missing canonical URL tag
Checks for a <link rel="canonical"> element.
Missing Twitter card meta tags
Checks for twitter:card meta tag for Twitter/X sharing.
No contact information found
Checks for a contact page link or email address.
No copyright notice
Checks for a copyright symbol or statement in the footer.
Missing favicon
Checks for a favicon link element in the page head.
No about page linked
Checks for a link to an about or about-us page.
No social media links
Checks for links to common social media platforms.
Hotlinked images from third-party domains
Checks for <img> and <source> elements pointing to external domains that are not known CDNs.
No feedback mechanism detected
Checks for feedback widgets, feedback buttons, or chat support widgets.
No request tracing headers on API responses
Checks API responses for x-request-id, x-trace-id, cf-ray, or x-vercel-id.
No demo or preview for non-signed-in visitors
Checks whether the homepage shows product output before requiring signup.
Know a failure mode we missed?
Suggest a check →