01-projects/squarely-puzzles

website amazon funnel audit

2026-05-13·audit·status: audit-complete-awaiting-founder-pick-on-refinements·! medium
squarelywebsiteamazon-funnelpolishinginbound-marketingaudit

Squarely website -> Amazon funnel audit (2026-05-13)

Summary

Live site is https://squarelypuzzle.com/ (Astro v6.1.9 on Cloudflare Pages, repo ~/Projects/squarely-web). The relaunch is materially shipped: 3 routes (/, /play, /tips), 3 Amazon book CTAs, a working web demo, a working waitlist API with welcome email, and Cloudflare Web Analytics wired up. There are 3 BLOCKER bugs that materially hurt funnel conversion right now: (a) og:url is hardcoded to http://localhost:4321/ so all social shares are mis-attributed; (b) og:squarely.png does not exist (SPA fallback serves HTML, so LinkedIn/Twitter/iMessage previews have no image); (c) footer + /play "Get notified" anchors point to non-existent IDs (#app, #email-capture) on every non-home page, dead-ending users. Amazon-funnel verdict: partial-leverage - the path home -> #books -> Amazon works in 2 clicks and the links are clean, but zero UTM tagging and zero Amazon Associates tag means we cannot measure or monetize the inbound at all. Strategy-aligned read: per STRATEGY.md the website is explicitly NOT the engine (Amazon Search/Browse is), so polish it enough to not embarrass us and stop dead-ending users, but do not invest in deep funnel work until KDP listing + Amazon Ads instrumentation is in flight.

Live state (2026-05-13 audit)

Polishing punchlist

BLOCKER (ship this cycle)

  1. B1 - og:url is hardcoded to localhost. src/layouts/Base.astro:25 sets canonicalUrl = Astro.url which at SSG build time resolves to http://localhost:4321/. Every Open Graph URL, every canonical link, every Twitter card URL points to localhost. Verified live: og:url content is http://localhost:4321/. Fix: hardcode const SITE = 'https://squarelypuzzle.com'; and compose URLs from Astro.url.pathname. Or set site in astro.config.mjs and use Astro.site.
  2. B2 - og:squarely.png does not exist. Live URL returns 200 but content-type is text/html (SPA fallback serves the home page HTML). Verified: curl -s https://squarelypuzzle.com/og-squarely.png returns <!DOCTYPE html>.... Every social share will show no preview image. public/ directory has app/, books/, doodles/, favicon.ico, favicon.svg, logo/, people/, videos/ but no og-squarely.png. Fix: generate and add a 1200x630 OG card.
  3. B3 - Dead #app anchor in every footer. Footer.astro:25 links to #app but no element on any page has that ID. Verified: document.getElementById('app') returns null on /, /play, /tips. Fix: either add id="app" to the iPhone-mockup half of EmailCapture.astro, or change the footer link to #get-waitlist.
  4. B4 - Dead #email-capture anchor on /play. /play "Get notified" CTA links to /#email-capture but the actual home section ID is #get-waitlist (and the title element ID is #email-capture-title). User clicks "Get notified" -> lands at top of home with no scroll. Fix: change /play link to /#get-waitlist.
  5. B5 - Footer anchors are relative on /play and /tips. Footer "How it works / Books / About John" links use href="#how-it-works" which resolves to /play/#how-it-works on the play page, and these IDs do not exist there. Footer nav is non-functional from /play and /tips. Fix: use absolute /#how-it-works, /#books, /#about in Footer.astro.

SHOULD (high-leverage but not blocking)

  1. S1 - Zero UTM tagging on any Amazon link. Three "Buy on Amazon" CTAs in Books.astro and one in Testimonials.astro point to bare https://www.amazon.com/dp/B0CD91ZLCY|B0DJ5SZRYN|B0FYNPYM1Z. Without ?tag=... and a source param, we cannot tell from KDP reports whether any inbound came from the website. Fix: add Associates tag + ?ref=squarelypuzzle.com&campaign=home_books_cta style param (Amazon strips most but tag= is honored). Also tag the welcome-email link in functions/api/waitlist.ts:65.
  2. S2 - No Amazon Associates tag. Beyond UTM, we are leaving the Associates affiliate cut on the table (~4-10% on each book sale via own-site referral). Founder owns the books, so the Associates fee is recoverable revenue we are not collecting. Fix: sign up for Amazon Associates if not already; append ?tag=YOUR_ASSOCIATES_TAG to every Amazon link.
  3. S3 - Cloudflare Web Analytics is CORS-blocked. Live console errors: Access to XMLHttpRequest at 'https://cloudflareinsights.com/cdn-cgi/rum' from origin 'https://squarelypuzzle.com' has been blocked by CORS policy. Analytics are NOT firing on the live site. Verify CF token + that the Web Analytics property is configured for the right origin in the dashboard. Until fixed, we have no traffic data and cannot answer "is the website driving Amazon clicks."
  4. S4 - No outbound-click tracking on Amazon CTAs. Even with CF Analytics fixed, by default it tracks pageviews not outbound clicks. Add a data-cf-click style event or wire a small gtag/plausible/CF Custom Event on each Amazon CTA. Without this, we cannot answer the founder's actual question.
  5. S5 - /play has no <h1>. Verified zero <h1> elements on /play. Hurts SEO and a11y. The "Squarely" wordmark next to the logo is a logo, not a heading. Fix: add visually-hidden or visible <h1>Play Squarely</h1>.
  6. S6 - /tips has no Amazon CTAs. A user lands on /tips (via search for "squarely tips" or sharing), watches 4 videos, and is offered only /play or /#books. No direct Amazon link. Fix: add a "Print editions" book-tile CTA at the bottom of /tips that links directly to Amazon Book 1 (with UTM), so visitors who prefer paper can convert without an extra hop.
  7. S7 - Hero "Get the books" CTA is a same-page anchor. Users scrolling fast from a paid ad land, see "Get the books", click, scroll to Books section, then must click again to reach Amazon. That is 3 clicks not 2. Fix: consider making the Hero primary CTA link directly to Book 1's Amazon page (with UTM); keep the "How it works" secondary CTA. Trade-off: same-page anchor preserves brand-pitch surface area; direct link wins on funnel speed.
  8. S8 - /tips videos have no poster attribute. Four autoplay-muted videos without posters. Creates Cumulative Layout Shift on first load and a blank frame before video data arrives. Fix: add a poster image per video (extract first frame to .webp).
  9. S9 - /tips videos lack aria-label and playsinline. Mobile Safari may not autoplay without playsinline. Verified: videos array shows autoplay:true, muted:true but no playsinline checked in audit. Fix: add playsinline attribute.
  10. S10 - No sitemap.xml. Returns the home HTML (SPA fallback). Hurts crawlability. Fix: add @astrojs/sitemap integration or hand-roll a static public/sitemap.xml.
  11. S11 - No robots.txt allow/sitemap line specific to Squarely. Current /robots.txt serves Cloudflare's default content-signals robots file. Should also reference the sitemap once it exists.

NICE-TO-HAVE

  1. N1 - Image alt on Amazon-CDN book covers could be richer. Currently alt="Squarely: Book 1 cover". Could include keywords: "Squarely: Book 1 - 100 logic puzzles by John H. Wilson - paperback cover". Marginal SEO + a11y win.
  2. N2 - Hero copy "Two rules" is great; everywhere else is verbose. Some sections (WarmStory, AboutJohn) have multi-paragraph blocks. Mobile users will bounce. Consider a "Show more" pattern or tighter copy on mobile. Defer to founder taste.
  3. N3 - Testimonials show 9 reviews but no link to all reviews. Trust signal could compound by linking "See more reviews on Amazon" deep-linked to the reviews tab of Book 1. Currently only the inline Amazon nudge link exists.
  4. N4 - No schema.org markup. Adding Product / Book JSON-LD on each book card would help Google show rich results in search. Mid-effort, mid-payoff.
  5. N5 - /play "Coming soon" iOS card has no concrete date. "Daily puzzles, leaderboards, streaks. Get notified." is fine, but if a TestFlight date is known it would convert better.
  6. **N6 - WebGame teaser on home links to /play but says "Twelve sample puzzles across four difficulty tiers" while /play shows three sample puzzles per tier (12 total, four tiers). Copy is technically correct; the off-by-one feel might benefit from re-phrasing as "Twelve sample puzzles, four tiers".

Amazon-funnel state

What works

What does not work

Primary CTAs and destinations

Surface CTA text Destination UTM? Direct to Amazon?
Home hero "Get the books" /#books (in-page anchor) n/a No (2 clicks needed)
Home hero "How it works" /#how-it-works n/a No
Home WebGame "Start playing" /play n/a No
Home Books x3 "Buy on Amazon" amazon.com/dp/ASIN No Yes (1 click from Books section)
Home Testimonials "Amazon" amazon.com/dp/B0CD91ZLCY No Yes
Home EmailCapture "play it right now" /play n/a No
/play "Get the books" /#books n/a No (2 clicks)
/play "Get notified" /#email-capture (DEAD ANCHOR) n/a No
/tips x4 "Try it on the play page" /play n/a No
/tips "Get the books" /#books n/a No (2 clicks)
Welcome email "The puzzle books are on Amazon" amazon.com/dp/B0CD91ZLCY No Yes

Conversion-friction count

Clicks from landing on home to opening Amazon Book 1 listing:

For comparison, a "buy now" direct link in the Hero would be 1 click from home. The trade is fewer eyes on the brand pitch.

Recommendations

Ship this cycle (~3-4 hours total)

The BLOCKER set is small and mechanical. Strong "do it now" recommendation:

  1. Fix og:url to be the production URL (Base.astro) - 5 min
  2. Generate and ship og-squarely.png (1200x630, can be Hero board screenshot with wordmark overlay) - 30 min
  3. Fix the dead #app and #email-capture anchors - either change the IDs in components or change the links in Footer/play - 10 min
  4. Make footer anchors absolute (/#books not #books) - 5 min
  5. Add UTM + Associates tag to all 5 Amazon links (3 in Books, 1 in Testimonials, 1 in welcome email) - 20 min. Use a single helper: amazonUrl(asin, source) that returns https://www.amazon.com/dp/${asin}?tag=${ASSOC_TAG}&linkCode=...&campaign=${source}.
  6. Debug Cloudflare Web Analytics CORS error - probably a token/origin misconfiguration in the CF dashboard. 15 min.
  7. Add outbound-click tracking to Amazon CTAs (custom event via CF Web Analytics or Plausible) - 30 min.
  8. Add <h1>Play Squarely</h1> to /play - 5 min.

After these eight, we have a clean enough funnel to actually measure whether the website is driving Amazon clicks.

Founder decision needed

Park for now

Continue-vs-park read on website-as-Amazon-funnel

Verdict: partial-leverage. Polish the obvious leaks, then park.

Per STRATEGY.md, the explicit thesis is that the website is NOT the engine - Amazon Search/Browse is. The website's job is brand/discovery support: a place where someone who heard about Squarely (via personal-network push, future iOS app shares, podcast mention) can land, get the story, and decide to buy on Amazon. It is a funnel exit, not a funnel entry.

At current state, with BLOCKERS present, the website is worse than a placeholder because broken anchors and missing OG images actively dead-end users who otherwise would have converted. After the 3-4 hour BLOCKER + SHOULD fix pass, the website becomes a clean exit to Amazon: 1-2 clicks to a tracked, attributed Amazon link from any landing page.

For the website to be a load-bearing funnel, three things would have to be true:

  1. Material organic traffic exists (currently unknown - analytics are CORS-blocked, but baseline assumption is tens of visits/month, not hundreds)
  2. Outbound-click data shows >20% click-through to Amazon (industry baseline for direct-product landing pages)
  3. Amazon attribution data shows website-attributed conversions converting at competitive rates

None of these can be verified today. Step 1 of verifying them is fixing the BLOCKER+SHOULD list. After that, give it 30 days of fixed analytics and re-read.

The honest read for the founder: the website is brand/discovery. It is worth keeping clean (the 3-4 hours of polish) because it is a free funnel exit and an SEO surface that John H. Wilson can hand to puzzle reviewers/podcasts. It is NOT worth investing in deep funnel work, content marketing, or A/B testing - that energy goes to KDP listing optimization, Amazon Ads instrumentation (the founder-picked critical component per STRATEGY.md), and shipping the iOS app.