Docs index
Feature Reference

Parcel-Page Sitemap Generator

Status: Planned Issue: #164Bundle: SEO infrastructure for the Ag Bundle (depends on One-Click Parcel Report)

Parcel-Page Sitemap Generator

Status: Planned Issue: #164Bundle: SEO infrastructure for the Ag Bundle (depends on One-Click Parcel Report)

Goal

Phase a static-generation pipeline for indexable parcel-report URLs (townshipcanada.com/parcel/SE-14-29-21-W2). Target 100K+ Canadian quarter sections by week 16. This is the AcreValue-for-Canada SEO wedge — search-driven acquisition for the Ag Bundle.

Phased rollout

PhaseWeekParcel pagesSelection
1510,000Representative sample across Prairie provinces
2860,000All AB quarter sections + sample SK/MB
316120,000All AB + all SK + sample MB + initial BC/ON cells

Phasing matters because:

  • Sudden submission of 120K URLs to Search Console tends to be deprioritized by Googlebot
  • Phase 1 lets us measure crawl rate, click-through, conversion before committing to the full surface
  • Each phase's selection can favour high-search-volume areas (Red Deer / Lacombe / Calgary corridor first)

Selection criteria for parcel inclusion

Not every quarter section in the DLS database should be in the sitemap. Selection rules:

  1. Coverage filter — only include quarters where we can populate the free-tier report cards with non-empty data:
    • Legal description (always available — parser-driven)
    • LSRS score (available wherever AAFC LSRS coverage exists)
    • Crop history (available for Prairie + parts of ON/BC)
  2. Province balance — target distribution across AB / SK / MB / BC / ON proportional to the agricultural land base in each
  3. Geographic spread — avoid clustering all 10K phase-1 pages in two RMs; distribute across at least 50 RMs
  4. Recency bias — favour parcels with recent AAFC crop inventory data over parcels in fallow / non-cultivated zones

Generator script

A new node script at scripts/generate-parcel-sitemap.js runs against the PostGIS quarter-section table and emits a list of LLD slugs that meet the selection criteria for the current phase. Output is data/parcel-sitemap-phase-N.json — committed to source so the runtime sitemap handler can read it without hitting the database on every request.

node scripts/generate-parcel-sitemap.js --phase=1 --target=10000
→ writes data/parcel-sitemap-phase-1.json

The script is idempotent — re-running it for the same phase produces the same output unless the source data has changed.

Sitemap handler

The existing server/api/__sitemap__/urls.get.ts is extended to read data/parcel-sitemap-phase-N.json for the current phase and emit one <url> entry per parcel with:

  • loc: /parcel/<lld-slug>
  • changefreq: monthly
  • priority: 0.5 (parcel pages are deeper than primary marketing pages)
  • lastmod: the date the parcel-sitemap-phase-N.json file was generated

The handler also splits the sitemap once URL count exceeds Google's 50K-per-sitemap limit. Phase 3 will require a sitemap index pointing to multiple sub-sitemaps.

Server-side rendering

Every parcel URL in the sitemap must render as static HTML on first request (no client-side hydration before the bot sees content). The Vue page app/pages/parcel/[lld].vue (defined in #157) uses defineRouteRules({ prerender: false }) plus the useAsyncData SSR pattern to ensure the bot crawl sees a complete document.

ISR is preferred over full prerender at this scale — 120K static files would inflate the build artifact significantly. ISR with a 24-hour revalidation window keeps the generated HTML fresh enough for crawler indexing without bloating builds.

Search Console submission

After each phase ships:

  1. Verify a sample of generated URLs render correctly in production
  2. Submit the updated sitemap.xml to Google Search Console
  3. Track "Indexed pages" as the leading SEO metric (the acceptance criterion)
  4. Monitor crawl stats and 4xx/5xx rates — the runtime handler should never 404 on a sitemap-listed URL

Acceptance criteria progress

  • scripts/generate-parcel-sitemap.js — phased selection logic
  • data/parcel-sitemap-phase-1.json — initial 10K entries
  • Sitemap handler extension to include parcel URLs
  • Sitemap index for phase 3 (split across multiple sub-sitemaps)
  • Server-side rendering of /parcel/[lld] pages (depends on #157)
  • Search Console resubmission process documented
  • Indexed-pages metric tracked weekly

Open questions

  • Selection bias — should phase 1 favour high-search-volume areas (more conversions per indexed page) or distributed coverage (better long-tail capture)?
  • Lastmod cadence — bumping lastmod on every sitemap regeneration causes Googlebot to recrawl frequently. Strategy: only bump lastmod when the underlying data for that specific parcel has changed (e.g., new AAFC year released).