diff --git a/src/views/ad-unit.tsx b/src/views/ad-unit.tsx index a61b4d7..cc9c666 100644 --- a/src/views/ad-unit.tsx +++ b/src/views/ad-unit.tsx @@ -38,10 +38,14 @@ const NO_AD_SEGMENTS = new Set([ 'revisions', ]); -/** Public, indexable pages only. A noindex page is a dashboard or a one-off flow. */ +/** + * Public, indexable pages only. A noindex page is a dashboard or a one-off flow, + * and the homepage carries no ad. + */ export function showsAd(path: string, noindex?: boolean): boolean { if (noindex) return false; const first = path.split(/[/?#]/)[1] ?? ''; + if (first === '') return false; return !NO_AD_SEGMENTS.has(first); } diff --git a/test/views.test.ts b/test/views.test.ts index 508ecef..08a47a2 100644 --- a/test/views.test.ts +++ b/test/views.test.ts @@ -561,7 +561,7 @@ test('the ad unit is a crawlproof frame on public pages only, and the policy fra const { showsAd, AD_SLOT } = await import('../dist/views/ad-unit.js'); const { Layout } = await import('../dist/views/layout.js'); const { securityHeaders } = await import('../dist/server/middleware.js'); - assert.equal(showsAd('/', false), true); + assert.equal(showsAd('/', false), false, 'the homepage carries no ad'); assert.equal(showsAd('/jobs/abc', false), true); assert.equal(showsAd('/me/settings', false), false); assert.equal(showsAd('/post-a-job', false), false); @@ -579,10 +579,11 @@ test('the ad unit is a crawlproof frame on public pages only, and the policy fra children: 'x', }), ); - const home = page('/'); - assert.equal(home.match(/crawlproof\.com\/api\/ads\/frame/g)?.length, 1, 'exactly one unit'); - assert.ok(home.includes(`slot=${AD_SLOT}&format=text_link`), home); - assert.ok(!home.includes('theme='), 'the frame answers prefers-color-scheme itself'); + assert.ok(!page('/').includes('/api/ads/frame'), 'no ad on the homepage'); + const job = page('/jobs/abc'); + assert.equal(job.match(/crawlproof\.com\/api\/ads\/frame/g)?.length, 1, 'exactly one unit'); + assert.ok(job.includes(`slot=${AD_SLOT}&format=text_link`), job); + assert.ok(!job.includes('theme='), 'the frame answers prefers-color-scheme itself'); assert.ok(!page('/inbox').includes('/api/ads/frame'), 'no ad inside the inbox'); const headers = new Headers(); diff --git a/web/public/app.css b/web/public/app.css index 7323029..4ca7150 100644 --- a/web/public/app.css +++ b/web/public/app.css @@ -1104,7 +1104,7 @@ a.badge-plain:hover .badge { /* CrawlProof ad unit (src/views/ad-unit.tsx): one fluid text_link frame at the top of the content. */ .ad-unit { - margin: 0 0 1.5rem; + margin: 0 0 0.75rem; } .ad-unit iframe { display: block; diff --git a/web/public/sw.js b/web/public/sw.js index 65f77aa..302caaf 100644 --- a/web/public/sw.js +++ b/web/public/sw.js @@ -13,7 +13,7 @@ * drifted, which is the only version of this rule that survives contact. */ -const VERSION = 'b264b667'; +const VERSION = '3a3325d0'; const SHELL = `shell-${VERSION}`; const ASSETS = ['/assets/app.css', '/assets/tokens.css', '/assets/icon.svg'];