GEO Implementation: AI Search Visibility & Citation Optimisation | A Square Solutions

4JSON-LD schema types deployed
718internal links normalised (posts)
3GEO cluster posts linked to service
6schema bugs fixed pre-deploy
120wmax passage length criterion
5speakable CSS selectors targeted

Starting Condition: A Draft Page, a Wrong Slug, and 718 Posts Pointing Nowhere

Before this implementation, asquaresolution.com had a draft GEO service page with the slug services-geo-seo (WordPress auto-appended the parent slug because no parent page existed yet). There was no /services/ parent page. All internal CTAs — across 748 posts — linked to /services/, a page with no service architecture, no schema, and no AI-search-ready content structure.

The site’s main GEO content lived in three blog posts (IDs 8717, 25641, 17157) with strong topical authority but no connection to a service page. From an AI search perspective, there was no “entity” for the GEO service — just orphaned content and a draft page with the wrong URL.

Why this matters for AI citation: AI search systems construct their answers from structured entity relationships, not just crawled text. Without a coherent /services/geo-seo/ page linked from topical authority posts, with schema that co-references the site’s Organisation entity, the GEO service had no citation architecture.

What We Set Out to Build

  • 1

    A published /services/ parent page with correct schema hierarchy and service card architecture for all planned child services.

  • 2

    A published /services/geo-seo/ page with passage-level GEO structure, complete JSON-LD schema, speakable markup, and AI citation-ready content architecture.

  • 3

    Internal link normalisation: all 718+ posts pointing to /services/ updated to point to /services/ — without 301 redirects.

  • 4

    GEO cluster linkage: the three topical authority posts (8717, 25641, 17157) linked to /services/geo-seo/ with contextual service cards.

  • 5

    Schema integrity: no audienceType arrays, no mismatched @id fragments, no currency errors, no duplicated BreadcrumbList definitions.

Implementation Approach: Staged, No-Redirect Architecture

The constraint was clear: no 301 redirects at any stage. Redirecting /services/ to /services/ before the new architecture was solid would damage any residual ranking signal. Instead, we used a staged parallel migration:

  1. 1

    Create /services/ (published) and set /services/geo-seo/ as a child with correct slug.

  2. 2

    Set canonical on /services/ pointing to /services/ — a soft signal, not a redirect.

  3. 3

    Normalise all internal /services/ links to /services/ via batched REST API updates.

  4. 4

    Add service cards linking from GEO cluster posts to /services/geo-seo/.

The 301 redirect from /services/ to /services/ is a Phase 4 action, deferred until GSC data confirms the new architecture has been crawled and indexed.

Schema Architecture: Four Types, One Co-Reference Chain

The /services/geo-seo/ page deploys four JSON-LD schema types in a single @graph block, linked by @id co-references:

WebPage @id: /services/geo-seo/#webpage
└ isPartOf → /#website
└ publisher → /#organization
└ breadcrumb → /services/geo-seo/#breadcrumb (reference only)

BreadcrumbList @id: /services/geo-seo/#breadcrumb
└ Home (pos 1) → asquaresolution.com
└ Services (pos 2) → /services/
└ GEO Services (pos 3) → /services/geo-seo/

Service @id: /services/geo-seo/#service
└ provider → /#organization
└ areaServed: [“GB”,”US”,”CA”,”AU”,”IE”]
└ offers: Offer (free audit, price:0, priceCurrency:”GBP”)

FAQPage @id: /services/geo-seo/#faqpage
└ 6 Question/Answer pairs (standalone, citable)

The speakable specification targets five CSS selectors: .gs-h1, .gs-hero-sub, .gs-faq-a, .gs-audit-headline, .gs-geo-definition. These correspond to the page elements most likely to be extracted as AI citation passages.

Passage Architecture: What Makes a Passage Citable

RAG (Retrieval-Augmented Generation) systems select passages based on semantic match and structural clarity. Our passage engineering criteria, derived from AI Execution Lab citation testing:

  • Direct opening sentence: the first sentence must answer the implicit question without requiring context from surrounding text. “Entity SEO is the practice of…” not “As we discussed above…”

  • Self-contained under 120 words: passages that require the reader to have read the preceding paragraph are not retrievable as standalone citations. Every key passage was written to function as an extracted excerpt.

  • Entity named in the passage: “Generative Engine Optimization (GEO) is…” not “This service is…” — AI systems need explicit entity naming within the passage, not in surrounding context.

  • Speakable-targeted: the definitional passage (.gs-geo-definition) was structured as the single most citable definition on the page — 47 words, direct, entity-named.

Lab reference: Citation pattern testing for the passage structure criteria is documented at https://lab.asquaresolution.com/labs/2026-05-18-geo-entity-density-experiment

Documented Failures and Fixes

These are the actual failures encountered during this implementation. They are documented because understanding failure modes is more useful than a clean success narrative.

Failure 1: WordPress Slug Auto-Modification

When we created the GEO draft page with slug geo-seo before the /services/ parent page existed, WordPress silently changed the slug to services-geo-seo (appending the intended parent slug). The page went live at the wrong URL.

Fix: Created the /services/ parent page first (ID 25771), then set the GEO page’s slug to geo-seo with parent: 25771 in the same API call. WordPress then assigned the correct nested URL /services/geo-seo/.

Lesson: When creating child pages via the WordPress REST API, the parent page must exist before setting the child slug. Parent-first creation order is mandatory for correct URL assignment.

Failure 2: Rank Math Canonical Not Accessible via REST

Attempting to set _rank_math_canonical_url via the REST API meta field returned HTTP 200 but did not persist the value. The saved meta response contained only Astra theme keys — Rank Math’s meta fields are not registered for REST API access by default.

Fix: Manual wp-admin action documented as a blocker: Rank Math → Edit /services/ → Advanced tab → Canonical URL → https://asquaresolution.com/services/

Lesson: Rank Math meta fields require explicit REST API registration. Do not assume page meta is writable via REST without first confirming the registered fields for the specific plugin version.

Failure 3: CSS Unicode Escape in Python String

Writing content:'92' in a Python string produced content:'92' in the saved CSS. Python interpreted  as an octal escape character (chr(2)), stripping the visible character and leaving only 92.

Fix: Double-escape in Python: content:'\2192' produces the literal string content:'92' in the CSS output. This applies to any CSS Unicode escape written inside a Python string literal.

Lesson: Python string escaping and CSS Unicode escaping interact. Always verify CSS arrow characters render correctly in live content — not just in the Python source.

Failure 4: Schema Validation False Negatives

Verification checks for BreadcrumbList position 2 URL and WebPage breadcrumb reference initially returned false negatives. The check strings contained regex-style wildcards (.*) used as plain string matches, which never evaluate as True regardless of content.

Fix: Replaced pattern-matching checks with re.findall() and re.search() calls. Confirmed correct content via direct GET requests with explicit pattern matching.

Pre-existing Blocker: legalName Typo in Knowledge Graph

The Rank Math Knowledge Graph had legalName: "cantact" (typo) instead of "A Square Solutions". This propagates through the Organization @id co-reference chain to all pages on the site — the entity name in structured data is incorrect site-wide.

Status: Manual fix required. Rank Math → Titles & Meta → Knowledge Graph → Organisation Name. Not fixed programmatically — requires admin UI access.

Structural Outcomes and What to Measure

The following structural outcomes are confirmed as of deployment date. Traffic and citation metrics will be measured at 30, 60, and 90 days post-deployment against the baselines established below.

OutcomeMeasurementStatus
/services/ hub page liveHTTP 200, indexed in GSCConfirmed (ID 25771)
/services/geo-seo/ live at correct URLHTTP 200, slug=geo-seo, parent=25771Confirmed (ID 25768)
4 JSON-LD schema types deployedRich Results Test passConfirmed
718 posts: internal links normalised0 remaining /services/ refs in postsConfirmed (spot-check 30 posts)
GEO cluster posts linked to /services/geo-seo/Posts 8717, 25641, 17157 contain service cardConfirmed
Schema bugs resolvedaudienceType, priceCurrency, @id fragments, BreadcrumbList deduplicatedConfirmed

Metrics to Track at 30 / 60 / 90 Days

MetricToolBaseline
AI Overview appearances for “generative engine optimization services”Manual Google search, SGE tracking0 at deploy date — page was draft
ChatGPT Search citations for GEO service queriesManual ChatGPT Search sampling, 20-query set0 at deploy date
Perplexity citations for GEO queriesManual Perplexity sampling, same 20-query set0 at deploy date
GSC Coverage: /services/geo-seo/ indexedGoogle Search ConsoleNot yet indexed at deploy
GSC impressions for /services/geo-seo/Google Search Console → Performance0 at deploy date
Rich Results eligibilityRich Results Test, Google Search Console → EnhancementsAll 4 schema types pass Rich Results Test

⚠ Remaining to Complete This Case Study

  • Screenshot: Google Search Console coverage graph showing /services/geo-seo/ indexing status at 30 days
  • Screenshot: First AI Overview or ChatGPT citation appearance for a GEO-related query
  • Screenshot: Rich Results Test pass for all 4 schema types on live URL
  • Data: GSC impressions/clicks for /services/geo-seo/ at 30/60/90 days
  • Data: Citation count across 3 AI systems at 30/60/90 days vs. 0 baseline
  • Fix: legalName typo must be resolved before Organization schema can be called fully correct

Tooling Used in This Implementation

Python 3 + requests
WordPress REST API
Schema Markup Validator
Rich Results Test
Screaming Frog SEO Spider
Google Search Console
Claude API (passage QA)
Rank Math SEO
LiteSpeed Cache

Phased Delivery Timeline

Phase 1Architecture Foundation/services/ hub created, GEO page slug corrected, 6 schema bugs fixed, page published. Runtime: ~4 hours of implementation + ~66 min bulk post migration.
Phase 2Link Migration718 posts migrated via batched Python/REST (25/batch, 1.2s sleep). 7 pages updated. GEO cluster service cards appended. UK page updated. Total: ~70 minutes automated.
Phase 3Service Pages (Draft)4 draft child service pages created: entity-seo, technical-seo, ai-automation, ai-consulting. All with full schema, CSS, content architecture.
Trust PassEvidence & MethodologyMethodology sections, tooling stacks, limitations blocks, Lab integration added to all 5 service pages.
Phase 4Redirect (Pending)/services/ → /services/ 301 redirect. Deferred until GSC confirms new architecture indexed. Estimated: Week 6–8 post-launch.

What We’d Do Differently

Lesson 1

Create parent pages before children, always. WordPress’s slug auto-modification is silent and immediate. Any batch page creation script should verify parent existence and create the hierarchy top-down, never assuming WordPress will hold the intended slug for a child-to-be-attached page.

Lesson 2

Audit REST-accessible meta fields before assuming writeability. Plugin meta fields (Rank Math, SEOPress, etc.) are not automatically accessible via the WordPress REST API. Run a field discovery request against /wp/v2/pages/schema before any bulk meta operation to confirm which meta keys are registered.

Lesson 3

Validate schema @id chains top-down, not schema-type by schema-type. The BreadcrumbList deduplication error and audienceType array format were both caught by top-down chain validation — checking that every @id reference resolves to a valid defined entity in the same @graph. Type-by-type validation misses cross-reference errors.

Lesson 4

Idempotent operations are mandatory for any bulk content change. The skip-if-unchanged check prevented double-processing 30 posts that had been updated in an earlier partial run. Without idempotency, re-running a migration after a failure creates duplicate content or corrupted internal links.

Lesson 5

Passage architecture requires a structural criterion, not a length guideline. “Keep it short” is not an actionable passage specification. The criterion “first sentence must answer the implicit question without context from surrounding text” is actionable, testable, and produces consistently better citation candidates than word-count guidance alone.

🤖 Ask Our AI — A Square Solutions