{
 "title": "State of app homepages on VibeKing",
 "edition": "October 2026 edition",
 "url": "https://vibeking.fun/reports/state-of-app-homepages",
 "published": "2026-10-25",
 "checked": "2026-10-25",
 "scanner": {
  "name": "VibeKing Vibe Check engine (src/vibeCheckEngine.js, collectFacts + scoreFacts)",
  "commit": "5c4049c"
 },
 "publisher": "VibeKing (vibeking.fun)",
 "citeAs": "VibeKing (2026). State of app homepages on VibeKing, October 2026 edition. Data checked 2026-10-25. https://vibeking.fun/reports/state-of-app-homepages",
 "sample": {
  "liveListingsWithUrl": 2353,
  "leftOutOwnSites": 4,
  "leftOutBelowSiteRoot": 211,
  "leftOutDuplicateHost": 0,
  "leftOutAntivirusInterception": 73,
  "scanned": 2065,
  "fromPublicDirectoryImport": 1988,
  "withBuildToolKnown": 112,
  "answered": 2005
 },
 "toolColumnMinimum": 30,
 "toolsBelowMinimum": [
  {
   "tool": "Claude",
   "appsInSample": 11
  },
  {
   "tool": "v0",
   "appsInSample": 10
  },
  {
   "tool": "Cursor",
   "appsInSample": 4
  },
  {
   "tool": "Base44",
   "appsInSample": 3
  },
  {
   "tool": "ChatGPT",
   "appsInSample": 3
  },
  {
   "tool": "Replit",
   "appsInSample": 3
  },
  {
   "tool": "Copilot",
   "appsInSample": 1
  },
  {
   "tool": "Gemini",
   "appsInSample": 1
  },
  {
   "tool": "GPT-4",
   "appsInSample": 1
  }
 ],
 "note": "Aggregate counts only. percent = round(count / n * 100). Page speed and the overall Vibe Check score are not included. No app is named.",
 "metrics": [
  {
   "metric": "listings_live",
   "group": "listings",
   "label": "Approved listings marked live by VibeKing's own liveness probe",
   "count": 2353,
   "n": 2638,
   "percent": 89,
   "definition": "Share of all approved VibeKing listings whose URL answered VibeKing's scheduled liveness probe at its last check (a status that refuses bots, such as 403 or 429, also counts as an answer)."
  },
  {
   "metric": "answered",
   "group": "sample",
   "label": "Answered with a page",
   "count": 2005,
   "n": 2065,
   "percent": 97,
   "definition": "The homepage returned an HTML page: not an error, a bot wall or a failed connection."
  },
  {
   "metric": "blocked",
   "group": "sample",
   "label": "Turned automated checks away",
   "count": 48,
   "n": 2065,
   "percent": 2,
   "definition": "An explicit refusal: HTTP 403, 429 or 503, or a bot challenge page."
  },
  {
   "metric": "failed",
   "group": "sample",
   "label": "Did not answer with a page",
   "count": 12,
   "n": 2065,
   "percent": 1,
   "definition": "A timeout, a failed connection (refused, reset or a TLS error), a DNS error, another HTTP error, or a response that was not a web page."
  },
  {
   "metric": "title",
   "group": "all",
   "label": "Has a page title",
   "count": 1986,
   "n": 2005,
   "percent": 99,
   "definition": "A non-empty <title> in the HTML the server sends."
  },
  {
   "metric": "titleLen",
   "group": "all",
   "label": "Title is 25 to 65 characters",
   "count": 1582,
   "n": 2005,
   "percent": 79,
   "definition": "Title length between 25 and 65 characters (the Vibe Check pass range)."
  },
  {
   "metric": "desc",
   "group": "all",
   "label": "Has a meta description",
   "count": 1878,
   "n": 2005,
   "percent": 94,
   "definition": "A non-empty meta name=\"description\"."
  },
  {
   "metric": "descLen",
   "group": "all",
   "label": "Description is 70 to 170 characters",
   "count": 1361,
   "n": 2005,
   "percent": 68,
   "definition": "Meta description length between 70 and 170 characters."
  },
  {
   "metric": "canonical",
   "group": "all",
   "label": "Has a canonical link",
   "count": 1562,
   "n": 2005,
   "percent": 78,
   "definition": "A link rel=\"canonical\" in the head."
  },
  {
   "metric": "sitemap",
   "group": "all",
   "label": "Has a valid sitemap",
   "count": 1702,
   "n": 2005,
   "percent": 85,
   "definition": "The sitemap named in robots.txt, or /sitemap.xml, answers 200 with a <urlset> or <sitemapindex>."
  },
  {
   "metric": "robots",
   "group": "all",
   "label": "Has a robots.txt",
   "count": 1788,
   "n": 2005,
   "percent": 89,
   "definition": "/robots.txt answers 200 with plain text, not an HTML page."
  },
  {
   "metric": "ogImage",
   "group": "all",
   "label": "Has a share image (og:image)",
   "count": 1618,
   "n": 2005,
   "percent": 81,
   "definition": "An og:image, og:image:url or twitter:image meta tag."
  },
  {
   "metric": "jsonLd",
   "group": "all",
   "label": "Has JSON-LD structured data",
   "count": 1415,
   "n": 2005,
   "percent": 71,
   "definition": "At least one script type=\"application/ld+json\" block."
  },
  {
   "metric": "indexable",
   "group": "all",
   "label": "Open to search engines",
   "count": 1991,
   "n": 2005,
   "percent": 99,
   "definition": "No noindex in a robots meta tag or X-Robots-Tag header, and robots.txt does not block Googlebot from /."
  },
  {
   "metric": "llms",
   "group": "all",
   "label": "Publishes /llms.txt",
   "count": 979,
   "n": 2005,
   "percent": 49,
   "definition": "/llms.txt answers 200 with more than 20 characters of plain text, not an HTML page."
  },
  {
   "metric": "aiBots",
   "group": "all",
   "label": "Lets GPTBot, ClaudeBot and PerplexityBot in",
   "count": 1903,
   "n": 2005,
   "percent": 95,
   "definition": "robots.txt does not disallow / for any of the three (no robots.txt allows them by default)."
  },
  {
   "metric": "readable",
   "group": "all",
   "label": "Readable: 600+ characters of text",
   "count": 1706,
   "n": 2005,
   "percent": 85,
   "definition": "600 or more characters of visible text in the server HTML, scripts and styles removed."
  },
  {
   "metric": "partial",
   "group": "all",
   "label": "Thin: 200 to 599 characters",
   "count": 39,
   "n": 2005,
   "percent": 2,
   "definition": "200 to 599 characters of visible text in the server HTML."
  },
  {
   "metric": "shell",
   "group": "all",
   "label": "App shell: under 200 characters",
   "count": 260,
   "n": 2005,
   "percent": 13,
   "definition": "Under 200 characters of visible text in the server HTML: the page is filled in by JavaScript."
  },
  {
   "metric": "https",
   "group": "all",
   "label": "Served over HTTPS",
   "count": 2005,
   "n": 2005,
   "percent": 100,
   "definition": "The homepage ends up on an https:// address after redirects."
  },
  {
   "metric": "hsts",
   "group": "all",
   "label": "Sends HSTS",
   "count": 1316,
   "n": 2005,
   "percent": 66,
   "definition": "A Strict-Transport-Security response header."
  },
  {
   "metric": "nosniff",
   "group": "all",
   "label": "Sends X-Content-Type-Options: nosniff",
   "count": 983,
   "n": 2005,
   "percent": 49,
   "definition": "An X-Content-Type-Options header containing nosniff."
  },
  {
   "metric": "csp",
   "group": "all",
   "label": "Sends a Content-Security-Policy",
   "count": 484,
   "n": 2005,
   "percent": 24,
   "definition": "A Content-Security-Policy header or meta http-equiv."
  },
  {
   "metric": "framing",
   "group": "all",
   "label": "Restricts framing",
   "count": 774,
   "n": 2005,
   "percent": 39,
   "definition": "An X-Frame-Options header, or frame-ancestors in the Content-Security-Policy."
  },
  {
   "metric": "median_text_chars",
   "group": "all",
   "label": "Median visible text in the server HTML (characters)",
   "count": 6159,
   "n": null,
   "percent": null,
   "definition": "Median of the visible-text character count across answered homepages."
  },
  {
   "metric": "title",
   "group": "Lovable",
   "label": "Has a page title",
   "count": 78,
   "n": 80,
   "percent": 98,
   "definition": "A non-empty <title> in the HTML the server sends."
  },
  {
   "metric": "titleLen",
   "group": "Lovable",
   "label": "Title is 25 to 65 characters",
   "count": 63,
   "n": 80,
   "percent": 79,
   "definition": "Title length between 25 and 65 characters (the Vibe Check pass range)."
  },
  {
   "metric": "desc",
   "group": "Lovable",
   "label": "Has a meta description",
   "count": 78,
   "n": 80,
   "percent": 98,
   "definition": "A non-empty meta name=\"description\"."
  },
  {
   "metric": "descLen",
   "group": "Lovable",
   "label": "Description is 70 to 170 characters",
   "count": 60,
   "n": 80,
   "percent": 75,
   "definition": "Meta description length between 70 and 170 characters."
  },
  {
   "metric": "canonical",
   "group": "Lovable",
   "label": "Has a canonical link",
   "count": 38,
   "n": 80,
   "percent": 48,
   "definition": "A link rel=\"canonical\" in the head."
  },
  {
   "metric": "sitemap",
   "group": "Lovable",
   "label": "Has a valid sitemap",
   "count": 64,
   "n": 80,
   "percent": 80,
   "definition": "The sitemap named in robots.txt, or /sitemap.xml, answers 200 with a <urlset> or <sitemapindex>."
  },
  {
   "metric": "robots",
   "group": "Lovable",
   "label": "Has a robots.txt",
   "count": 77,
   "n": 80,
   "percent": 96,
   "definition": "/robots.txt answers 200 with plain text, not an HTML page."
  },
  {
   "metric": "ogImage",
   "group": "Lovable",
   "label": "Has a share image (og:image)",
   "count": 78,
   "n": 80,
   "percent": 98,
   "definition": "An og:image, og:image:url or twitter:image meta tag."
  },
  {
   "metric": "jsonLd",
   "group": "Lovable",
   "label": "Has JSON-LD structured data",
   "count": 46,
   "n": 80,
   "percent": 57,
   "definition": "At least one script type=\"application/ld+json\" block."
  },
  {
   "metric": "indexable",
   "group": "Lovable",
   "label": "Open to search engines",
   "count": 80,
   "n": 80,
   "percent": 100,
   "definition": "No noindex in a robots meta tag or X-Robots-Tag header, and robots.txt does not block Googlebot from /."
  },
  {
   "metric": "llms",
   "group": "Lovable",
   "label": "Publishes /llms.txt",
   "count": 49,
   "n": 80,
   "percent": 61,
   "definition": "/llms.txt answers 200 with more than 20 characters of plain text, not an HTML page."
  },
  {
   "metric": "aiBots",
   "group": "Lovable",
   "label": "Lets GPTBot, ClaudeBot and PerplexityBot in",
   "count": 78,
   "n": 80,
   "percent": 98,
   "definition": "robots.txt does not disallow / for any of the three (no robots.txt allows them by default)."
  },
  {
   "metric": "readable",
   "group": "Lovable",
   "label": "Readable: 600+ characters of text",
   "count": 29,
   "n": 80,
   "percent": 36,
   "definition": "600 or more characters of visible text in the server HTML, scripts and styles removed."
  },
  {
   "metric": "partial",
   "group": "Lovable",
   "label": "Thin: 200 to 599 characters",
   "count": 5,
   "n": 80,
   "percent": 6,
   "definition": "200 to 599 characters of visible text in the server HTML."
  },
  {
   "metric": "shell",
   "group": "Lovable",
   "label": "App shell: under 200 characters",
   "count": 46,
   "n": 80,
   "percent": 57,
   "definition": "Under 200 characters of visible text in the server HTML: the page is filled in by JavaScript."
  },
  {
   "metric": "https",
   "group": "Lovable",
   "label": "Served over HTTPS",
   "count": 80,
   "n": 80,
   "percent": 100,
   "definition": "The homepage ends up on an https:// address after redirects."
  },
  {
   "metric": "hsts",
   "group": "Lovable",
   "label": "Sends HSTS",
   "count": 77,
   "n": 80,
   "percent": 96,
   "definition": "A Strict-Transport-Security response header."
  },
  {
   "metric": "nosniff",
   "group": "Lovable",
   "label": "Sends X-Content-Type-Options: nosniff",
   "count": 76,
   "n": 80,
   "percent": 95,
   "definition": "An X-Content-Type-Options header containing nosniff."
  },
  {
   "metric": "csp",
   "group": "Lovable",
   "label": "Sends a Content-Security-Policy",
   "count": 6,
   "n": 80,
   "percent": 8,
   "definition": "A Content-Security-Policy header or meta http-equiv."
  },
  {
   "metric": "framing",
   "group": "Lovable",
   "label": "Restricts framing",
   "count": 6,
   "n": 80,
   "percent": 8,
   "definition": "An X-Frame-Options header, or frame-ancestors in the Content-Security-Policy."
  },
  {
   "metric": "title",
   "group": "other than Lovable",
   "label": "Has a page title",
   "count": 1908,
   "n": 1925,
   "percent": 99,
   "definition": "A non-empty <title> in the HTML the server sends."
  },
  {
   "metric": "titleLen",
   "group": "other than Lovable",
   "label": "Title is 25 to 65 characters",
   "count": 1519,
   "n": 1925,
   "percent": 79,
   "definition": "Title length between 25 and 65 characters (the Vibe Check pass range)."
  },
  {
   "metric": "desc",
   "group": "other than Lovable",
   "label": "Has a meta description",
   "count": 1800,
   "n": 1925,
   "percent": 94,
   "definition": "A non-empty meta name=\"description\"."
  },
  {
   "metric": "descLen",
   "group": "other than Lovable",
   "label": "Description is 70 to 170 characters",
   "count": 1301,
   "n": 1925,
   "percent": 68,
   "definition": "Meta description length between 70 and 170 characters."
  },
  {
   "metric": "canonical",
   "group": "other than Lovable",
   "label": "Has a canonical link",
   "count": 1524,
   "n": 1925,
   "percent": 79,
   "definition": "A link rel=\"canonical\" in the head."
  },
  {
   "metric": "sitemap",
   "group": "other than Lovable",
   "label": "Has a valid sitemap",
   "count": 1638,
   "n": 1925,
   "percent": 85,
   "definition": "The sitemap named in robots.txt, or /sitemap.xml, answers 200 with a <urlset> or <sitemapindex>."
  },
  {
   "metric": "robots",
   "group": "other than Lovable",
   "label": "Has a robots.txt",
   "count": 1711,
   "n": 1925,
   "percent": 89,
   "definition": "/robots.txt answers 200 with plain text, not an HTML page."
  },
  {
   "metric": "ogImage",
   "group": "other than Lovable",
   "label": "Has a share image (og:image)",
   "count": 1540,
   "n": 1925,
   "percent": 80,
   "definition": "An og:image, og:image:url or twitter:image meta tag."
  },
  {
   "metric": "jsonLd",
   "group": "other than Lovable",
   "label": "Has JSON-LD structured data",
   "count": 1369,
   "n": 1925,
   "percent": 71,
   "definition": "At least one script type=\"application/ld+json\" block."
  },
  {
   "metric": "indexable",
   "group": "other than Lovable",
   "label": "Open to search engines",
   "count": 1911,
   "n": 1925,
   "percent": 99,
   "definition": "No noindex in a robots meta tag or X-Robots-Tag header, and robots.txt does not block Googlebot from /."
  },
  {
   "metric": "llms",
   "group": "other than Lovable",
   "label": "Publishes /llms.txt",
   "count": 930,
   "n": 1925,
   "percent": 48,
   "definition": "/llms.txt answers 200 with more than 20 characters of plain text, not an HTML page."
  },
  {
   "metric": "aiBots",
   "group": "other than Lovable",
   "label": "Lets GPTBot, ClaudeBot and PerplexityBot in",
   "count": 1825,
   "n": 1925,
   "percent": 95,
   "definition": "robots.txt does not disallow / for any of the three (no robots.txt allows them by default)."
  },
  {
   "metric": "readable",
   "group": "other than Lovable",
   "label": "Readable: 600+ characters of text",
   "count": 1677,
   "n": 1925,
   "percent": 87,
   "definition": "600 or more characters of visible text in the server HTML, scripts and styles removed."
  },
  {
   "metric": "partial",
   "group": "other than Lovable",
   "label": "Thin: 200 to 599 characters",
   "count": 34,
   "n": 1925,
   "percent": 2,
   "definition": "200 to 599 characters of visible text in the server HTML."
  },
  {
   "metric": "shell",
   "group": "other than Lovable",
   "label": "App shell: under 200 characters",
   "count": 214,
   "n": 1925,
   "percent": 11,
   "definition": "Under 200 characters of visible text in the server HTML: the page is filled in by JavaScript."
  },
  {
   "metric": "https",
   "group": "other than Lovable",
   "label": "Served over HTTPS",
   "count": 1925,
   "n": 1925,
   "percent": 100,
   "definition": "The homepage ends up on an https:// address after redirects."
  },
  {
   "metric": "hsts",
   "group": "other than Lovable",
   "label": "Sends HSTS",
   "count": 1239,
   "n": 1925,
   "percent": 64,
   "definition": "A Strict-Transport-Security response header."
  },
  {
   "metric": "nosniff",
   "group": "other than Lovable",
   "label": "Sends X-Content-Type-Options: nosniff",
   "count": 907,
   "n": 1925,
   "percent": 47,
   "definition": "An X-Content-Type-Options header containing nosniff."
  },
  {
   "metric": "csp",
   "group": "other than Lovable",
   "label": "Sends a Content-Security-Policy",
   "count": 478,
   "n": 1925,
   "percent": 25,
   "definition": "A Content-Security-Policy header or meta http-equiv."
  },
  {
   "metric": "framing",
   "group": "other than Lovable",
   "label": "Restricts framing",
   "count": 768,
   "n": 1925,
   "percent": 40,
   "definition": "An X-Frame-Options header, or frame-ancestors in the Content-Security-Policy."
  }
 ],
 "changelog": [
  {
   "date": "2026-10-25",
   "change": "October 2026 edition published: first run, over the live listings that link to a site's root."
  }
 ]
}