diff --git a/.github/workflows/app-discovery-qa.yml b/.github/workflows/app-discovery-qa.yml index 76671d1a..66f2f91c 100644 --- a/.github/workflows/app-discovery-qa.yml +++ b/.github/workflows/app-discovery-qa.yml @@ -4,6 +4,7 @@ on: branches: [main] paths: - apps.html + - index.html - apps_data.json - guides/** - sitemap.xml @@ -17,6 +18,7 @@ on: branches: [main] paths: - apps.html + - index.html - apps_data.json - guides/** - sitemap.xml diff --git a/docs/APP_DISCOVERY_GROWTH_RELEASE_2026-10-27.md b/docs/APP_DISCOVERY_GROWTH_RELEASE_2026-10-27.md index b10f732b..6228163c 100644 --- a/docs/APP_DISCOVERY_GROWTH_RELEASE_2026-10-27.md +++ b/docs/APP_DISCOVERY_GROWTH_RELEASE_2026-10-27.md @@ -18,9 +18,9 @@ bash scripts/publish_app_discovery.sh --apply bash scripts/check_app_discovery_live.sh ``` -Only these files transfer: `apps.html`, `sitemap.xml`, `guides/quick-games/index.html`, `guides/daily-habits/index.html`. Every other VPS file, including privacy, support, policy, payment and ads assets, stays untouched. To override environment use `APP_SITE_DEPLOY_HOST` and `APP_SITE_DEPLOY_ROOT` with a known-safe absolute path. The script refuses unknown flags/invalid targets. +Only these files transfer: `index.html`, `apps.html`, `sitemap.xml`, `guides/quick-games/index.html`, `guides/daily-habits/index.html`. The homepage links are tracked with `discovery_nav_click` and let visitors reach the search or guides without scrolling 92 cards. Every other VPS file, including privacy, support, policy, payment and ads assets, stays untouched. To override environment use `APP_SITE_DEPLOY_HOST` and `APP_SITE_DEPLOY_ROOT` with a known-safe absolute path. The script refuses unknown flags/invalid targets. -**Publish gate:** a dry-run is not publication. Only mark live once `check_app_discovery_live.sh` reports HTTP 200 and matches `id="find-app"`, both guide canonical URLs, guide click event and sitemap entries. After manual publication consider Google Search Console URL inspection and sitemap submission if the `appdevelopsk.com` property is available. +**Publish gate:** a dry-run is not publication. Only mark live once `check_app_discovery_live.sh` reports HTTP 200 and matches the homepage `discovery-links`, `id="find-app"`, both guide canonical URLs, guide click event and sitemap entries. After manual publication consider Google Search Console URL inspection and sitemap submission if the `appdevelopsk.com` property is available. ## Growth experiment — acquisition, not vanity pageviews diff --git a/index.html b/index.html index 5115e35c..3ef2b845 100644 --- a/index.html +++ b/index.html @@ -60,6 +60,8 @@ location: a.closest('footer') ? 'footer' : (a.closest('.hero') ? 'hero' : 'other'), link_url: href }); + } else if (a.classList.contains('discovery-link')) { + gtag('event', 'discovery_nav_click', { guide: a.getAttribute('data-guide') || 'catalog', origin: 'homepage' }); } else if (a.classList.contains('app-card')) { gtag('event', 'app_view', { app: href.replace(/^support\//, '').replace(/\/$/, '') }); } else if (/pickly\.blog|toolify365\.com|fxea365\.com/.test(href)) { @@ -298,6 +300,11 @@ .stats { grid-template-columns: repeat(2, 1fr); } .hero { padding-top: 100px; } } + + .discovery-links{display:flex;flex-wrap:wrap;justify-content:center;gap:12px;max-width:1100px;margin:10px auto 30px;padding:0 24px} + .discovery-links a{display:inline-flex;align-items:center;gap:6px;border:1px solid rgba(155,169,255,.5);border-radius:999px;padding:10px 16px;color:var(--text-primary);background:rgba(108,123,255,.13);text-decoration:none;font-weight:650;font-size:.91rem} + .discovery-links a:hover,.discovery-links a:focus-visible{outline:2px solid var(--accent);outline-offset:2px} + @@ -425,6 +432,11 @@

Travel & Maps

Featured Apps

A selection of our most popular apps across categories

+
SnapLingo diff --git a/scripts/check_app_discovery_live.sh b/scripts/check_app_discovery_live.sh index bc94cb9d..9ae3bce8 100644 --- a/scripts/check_app_discovery_live.sh +++ b/scripts/check_app_discovery_live.sh @@ -13,6 +13,9 @@ fetch() { -o "$tmp/$filename" -w '%{http_code}' "$base$route") [[ "$code" == 200 ]] || { echo "FAIL HTTP $code $base$route" >&2; exit 1; } } +fetch '/' 'index.html' +grep -Fq 'class="discovery-links"' "$tmp/index.html" || { echo 'FAIL homepage discovery links are stale' >&2; exit 1; } +grep -Fq 'discovery_nav_click' "$tmp/index.html" || { echo 'FAIL homepage discovery tracking is stale' >&2; exit 1; } fetch '/apps' 'apps.html' grep -Fq 'id="find-app"' "$tmp/apps.html" || { echo 'FAIL catalog search is stale' >&2; exit 1; } grep -Fq 'catalog_store_click' "$tmp/apps.html" || { echo 'FAIL store-click attribution is stale' >&2; exit 1; } diff --git a/scripts/publish_app_discovery.sh b/scripts/publish_app_discovery.sh index b157a397..bb6abf90 100644 --- a/scripts/publish_app_discovery.sh +++ b/scripts/publish_app_discovery.sh @@ -15,7 +15,7 @@ root="${APP_SITE_DEPLOY_ROOT:-/var/www/html}" if [[ ! "$host" =~ ^[a-zA-Z0-9_.@-]+$ || ! "$root" =~ ^/var/www/[a-zA-Z0-9_./-]+$ ]]; then echo 'Invalid APP_SITE_DEPLOY_HOST or APP_SITE_DEPLOY_ROOT' >&2; exit 2 fi -files=(apps.html sitemap.xml guides/quick-games/index.html guides/daily-habits/index.html) +files=(index.html apps.html sitemap.xml guides/quick-games/index.html guides/daily-habits/index.html) for file in "${files[@]}"; do [[ -s "$file" ]] || { echo "Missing source file: $file" >&2; exit 2; } done diff --git a/tests/catalog-growth.test.mjs b/tests/catalog-growth.test.mjs index 5868ca9f..2ed62bf8 100644 --- a/tests/catalog-growth.test.mjs +++ b/tests/catalog-growth.test.mjs @@ -69,3 +69,11 @@ test('guide landing pages link only to listed published applications and are dis assert.doesNotMatch(page,/aggregateRating|ratingValue|100% free|guaranteed/i); } }); + +test('homepage sends visitors to catalog and both indexable guides without a search gate',()=>{ + const home=read('index.html'); + assert.match(home,/class="discovery-links"/); + assert.match(home,/href="\/apps"/); + for (const slug of guides) assert.match(home,new RegExp('href="/guides/'+slug+'/"')); + assert.match(home,/discovery_nav_click/); +});