Conversation
Two AdSense content-hardening pages (adsense-plan §8.5.3 / §8.5.4): - /methodology explains the Residency Shift Index formula and bands, the SAL/SA2 geography, and each dataset's source, years, and limits. - /suburbs lists every Sydney/Melbourne suburb A-Z so all ~1494 suburb pages are click-reachable, via a new useAllSuburbs hook over the existing heatmap endpoint (no new backend). Both added to the prerendered sitemap and linked from the site footer.
feat: add methodology and all-suburbs index pages
Turn each suburb's "charts + numbers" page into one with human-readable prose, so the page reads as original content rather than templated filler (adsense-plan §8.5.1). A framework-free buildNarrative() assembles up to three paragraphs from the suburb's real ABS data: the rented-share trend plus the Residency Shift Index, the community mix (overseas-born share, top origin, top non-English languages), and the university-qualified share vs the city benchmark (with crime for Melbourne suburbs only, never fabricated where it 404s). Verbs and framing switch on numeric bands so suburbs read differently, not just with the place name swapped. SuburbNarrative reuses the five hooks SuburbCard already calls, so it shares the TanStack cache and fires no extra network requests.
feat: add per-suburb editorial narrative paragraph
Previously prerender only swapped <head>, so a reviewer viewing page source (and any non-JS crawler) saw an empty <div id="root"> — the shell that reads as Low value content (adsense-plan §8.5.6 step 7). Prerender now seeds each suburb page's #root with a real data-driven paragraph. It transpiles src/lib/narrative.ts on the fly via the installed typescript dep, so the same buildNarrative() the SuburbNarrative component uses is the single source of truth. Tenure is fetched per suburb through a concurrency-limited pool (a failed suburb degrades to a head-only page, never aborts the build). The seed goes inside #root: main.tsx mounts with createRoot(), which replaces #root on load, so real users get the full SPA and the prose is only ever seen pre-hydration or by crawlers — no duplicate content.
feat: prerender suburb narrative into the page body
Once AdSense ads run, the "there is no advertising" statements become false, and reviewers require an ads + cookies disclosure (adsense-plan §4). This page is also the Chrome Web Store privacy policy, so all ad wording is confined to the website and the extension is stated to carry no ads. - split the "In short" analytics bullet, add a website-only ads bullet - new Advertising subsection: AdSense funding, third-party cookies, opt-out links, and EEA/UK/CH consent - add a Google AdSense row to "Who processes your data" - replace the "we do not sell your data" line with an ads-aware version - bump the last-updated date
Site is registered in AdSense (publisher ca-pub-5982385876517812) and needs ownership verification plus an authorised-seller declaration before requesting review (adsense-plan §3.1 / §3.2). - add the AdSense loader script to index.html's <head>; prerender uses the built index.html as its template, so it propagates to every suburb page automatically - add public/ads.txt so the site declares Google as an authorised seller and the account stops warning about unauthorized sellers Ad units come after approval; this is verification only.
feat: AdSense verification + advertising privacy disclosure
|
Warning Review limit reached
Next review available in: 36 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (12)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What
Everything needed to apply to Google AdSense. Frontend only.
Content hardening — make the site read as a complete, navigable site with original value, not a pile of template pages:
/methodology— original reference page: Residency Shift Index formula & bands, SAL↔SA2 geography, per-dataset sources/years/limits./suburbs— A–Z index of every suburb (newuseAllSuburbshook over the existing heatmap endpoint), so all ~1494 suburb pages are click-reachable.buildNarrative(); reuses existing hooks so it fires no extra requests.<body>— seeds each suburb page's#rootwith that narrative (transpilingnarrative.tsfor a single source of truth), so a reviewer viewing page source / a non-JS crawler sees real content, not an empty shell.Registration & integration:
<script>inindex.html(publisherca-pub-5982385876517812) +public/ads.txt.Why
Groundwork before Request review: lower the risk of a
Low value content/Difficult site navigationrejection, satisfy ownership verification + the authorised-seller declaration, and make the required ads/cookies disclosure (the old "there is no advertising" wording becomes false once ads run). The/suburbsinternal-link hub also helps the current "discovered / 0 indexed" Search Console state.The narrative text is rule-based, not LLM-generated (bulk LLM generation would itself look like scaled-content abuse); each paragraph's value comes from that suburb's unique ABS data, with wording varied by numeric bands to avoid templated sameness.
Not included (post-approval): the
AdSlotcomponent & ad units (§3.5), the CMP consent banner, and tax/payment setup.How to test
cd frontend && npm run build— passes clean.npm run dev→ visit/methodology,/suburbs, and a suburb page (check the "In brief" card; a Melbourne suburb includes a crime sentence, Sydney does not). Footer links all resolve.VITE_API_BASE_URL=<api> npm run build:deploy→ log reportsN suburb pages (M with a seeded narrative);grep '<div id="root">' dist/suburb/<code>.htmlshows the seeded prose.curl -s https://www.suburblensapp.com/ads.txtreturns the pub line; a suburb page's source containsadsbygoogle.js?client=ca-pub-5982385876517812;/privacyshows the new Advertising section.