Skip to content

Make Vortex site discoverable in search and AI crawlers #1143

@Sharqiewicz

Description

@Sharqiewicz

As a prospective Vortex customer searching Google, ChatGPT, Claude, or Perplexity for cross-border crypto-fiat payment solutions - particularly in Brazil, Colombia, Argentina, the US, and Europe
I want to find vortexfinance.co content cited in search results and AI answers for "buy crypto" / "sell crypto" intents in my market
So that organic search and AI-mediated discovery become viable acquisition channels in our core operating jurisdictions - today the site is functionally invisible to all crawlers


Context

A full SEO audit was first run on 2026-05-11 and returned a Health Score of 20/100 — Critical.

The root cause is that https://www.vortexfinance.co/ is a pure client-side React SPA. Every URL (homepage, /business, /contact, /privacy-policy, /terms-and-conditions, /pt-BR/*) returns the identical 1,971-byte HTML shell containing only <title>Vortex</title>, a Google Tag Manager script, and <div id="app"></div>. Verified via curl — identical ETag (8aafe548fb71601e123130ba5c48d931-ssl) across all five tested routes. Googlebot indexes blank pages in its first pass; GPTBot, ClaudeBot, PerplexityBot, and Bing's AI crawler never execute JavaScript and see nothing at all.

Score breakdown

Category Weight Score
Technical SEO 25% 24
Content Quality 25% 28
On-Page SEO 20% 15
Schema / Structured Data 10% 0
Performance (CWV) 10% 25
Images 5% 30
AI Search Readiness 5% 4

Top critical findings (unchanged since May 11)

  1. Pure CSR — empty HTML shell on every URL; no SSR or prerendering.
  2. No meta description, Open Graph, Twitter Card, or canonical in static HTML.
  3. Bare <title>Vortex</title> on every page.
  4. Zero structured data (no Organization, FinancialService, BreadcrumbList, FAQPage).
  5. Live legal placeholder [●] in the governing-law clause of /terms-and-conditions — a YMYL trust failure.
  6. JS bundle is 7.8 MB uncompressed on a single chunk → LCP estimated 3.5–5s p75 on mobile.
  7. /pt-BR/ now returns HTTP 200 (one delta vs. May 11) but serves the same empty shell. /es/, /pt/, /fr/ still 404 despite robots.txt referencing them.
  8. robots.txt driftDisallow: /es/widget, /pt/widget, /fr/widget reference paths that 404.
  9. No hreflang tags despite multi-locale routing now partially in place.
  10. Asset cache headers missing immutable — content-hashed Vite bundles served with cache-control: public, max-age=0, must-revalidate.

Live SERP visibility check (target markets, 2026-05-21)

Market Query tested Top organic competitors Vortex
🇧🇷 Brazil "buy crypto PIX" / "comprar cripto PIX" BingX, Switchere, BitPay+Ramp, CEX.io, Ledger, Paybis, Gate.com, Symlix Not in top 100
🇦🇷 Argentina "comprar bitcoin Argentina" LiteFinance, Criptonoticias, Coinbase, Transak, Ripio, Lemon, Buenbit, Onramp Money Not in top 100
🇨🇴 Colombia "comprar crypto COP" / "comprar USDC Colombia" Wenia (Bancolombia), DolarApp, ChangeNOW, Coinbase, CriptoYa Not in top 100
🇪🇺 Europe "buy USDC EURC SEPA" Guardarian, Mt Pelerin, Bleap, Circle, RampNow, MoonPay Not in top 100
🇺🇸 United States "buy USDC ACH" Coinbase, Kraken, MoonPay, Transak, Ramp Network Not in top 100

Vortex appears in none of the target-market SERPs. Until acceptance criterion #1 ships, this will not change.


Acceptance Criteria

Critical (blocking — fix immediately)

  • A prerendering strategy is chosen and deployed (vite-plugin-ssg, Netlify Edge prerendering, or equivalent compatible with TanStack Router) — verified by curl -sL https://www.vortexfinance.co/business returning rendered HTML with visible body content, not just <div id="app"></div>
  • Each indexable route has a unique <title> and <meta name="description"> in the static HTML response — verified per URL via curl. Defaults must include target keywords ("buy crypto", "sell crypto", "non-custodial", payment-method names).
  • Each route has <link rel="canonical">, Open Graph (og:title, og:description, og:image, og:url), and Twitter Card metadata in static HTML
  • Organization and FinancialService JSON-LD are present in static <head> of every page, including areaServed, currenciesAccepted, paymentAccepted, sameAs properties, and validate cleanly in Google's Rich Results Test
  • The [●] placeholder in /terms-and-conditions governing-law clause is replaced with the actual governing jurisdiction

High (fix before geo-content work begins)

  • Locale URL structure decided and implemented as subdirectories: /pt-BR/, /es-AR/, /es-CO/, /es-MX/, /en-EU/, /en-US/. Each locale root returns HTTP 200 with prerendered content matching the locale.
  • <link rel="alternate" hreflang> tags for every supported locale plus x-default are present on every page in static HTML
  • WebSite + SearchAction JSON-LD on the homepage to enable sitelinks search box
  • apps/frontend/public/robots.txt matches the actual route structure (currently drifts vs. production). Remove Disallow entries for 404 paths. Decide whether /widget is noindex (meta) instead of Disallow (robots.txt) so link equity flows.
  • Security headers added via netlify.toml: Content-Security-Policy, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy, X-Frame-Options, and HSTS upgraded with includeSubDomains; preload
  • /assets/* hashed bundles return Cache-Control: public, max-age=31536000, immutable
  • JS bundle is code-split — initial entry chunk under 200 KB gzip (currently single 7.8 MB chunk = ~1.8 MB gzip). Marketing surface must not load the ramp-widget chunk (Polkadot.js, Wagmi, XState).
  • E-E-A-T pages exist with prerendered content and named individuals: /about (founders, jurisdiction, year founded), /team (LinkedIn links, credentials), /security (non-custodial architecture, Nabla AMM audit links), /compliance (regulatory status or explicit disclosure of partner-license model), /licenses. YMYL non-negotiable for US/EU ranking.

Medium (geo-targeted content — once prerendering and locale structure are in place)

  • Brazil (pt-BR) market pages shipped at 800–1,800 words each, all with FAQPage JSON-LD:
    • /pt-BR/comprar-cripto-com-pix (1,800w)
    • /pt-BR/vender-cripto-pix (1,600w)
    • /pt-BR/comprar-usdc-com-pix (1,500w)
    • /pt-BR/como-funciona (1,200w)
    • /pt-BR/taxas (800w)
  • Argentina (es-AR) market pages shipped:
    • /es-AR/comprar-cripto-con-pesos (1,800w)
    • /es-AR/vender-usdc-ars (1,600w)
    • /es-AR/comprar-usdc-argentina (1,500w)
    • /es-AR/como-funciona (1,200w)
    • /es-AR/comisiones (800w)
  • Colombia (es-CO) market pages shipped:
    • /es-CO/comprar-cripto-con-pesos-colombianos (1,800w)
    • /es-CO/vender-cripto-cop (1,600w)
    • /es-CO/comprar-usdc-colombia (1,500w)
    • /es-CO/onramp-cop (1,200w)
    • /es-CO/comisiones (800w)
  • Europe (en-EU) market pages shipped:
    • /europe/buy-eurc-sepa (2,000w)
    • /europe/sell-crypto-sepa (1,800w)
    • /europe/buy-usdc-europe (1,600w)
    • /europe/non-custodial-onramp (1,400w)
    • /europe/fees (800w)
  • United States (en-US) market pages shipped:
    • /usa/buy-usdc (2,000w)
    • /usa/sell-crypto-usd (1,800w)
    • /usa/non-custodial-crypto-onramp (1,600w)
    • /usa/fees (800w)
  • BreadcrumbList JSON-LD per route on every non-homepage page and locale equivalents
  • Each market page includes a 60–80 word "what is" definitional opener (AI citation snippet format), a comparison table with explicit column headers (LLM-extractable), and 5–8 FAQPage Q&A pairs (primary AI-citation lever)
  • Existing pages expanded to minimum word counts: / (600w), /business (1,000w), /contact (200w with physical/registered address), /privacy-policy (800w covering LGPD + GDPR), /terms-and-conditions (1,200w), /terms-and-conditions-full (2,000w)
  • Sitemap expanded to include all locale URLs with <lastmod> per entry and <xhtml:link rel="alternate"> hreflang annotations per entry
  • TrustedBy logo strip replaced with linked, dated partnership/coverage references; CoinDesk removed unless properly cited as editorial coverage
  • modulepreload for the entry JS chunk, dns-prefetch for googletagmanager.com, Red Hat Display self-hosted (or display=optional)

Verification

  • SEO Health Score re-audit shows ≥70/100 after Critical + High work is shipped
  • Google Search Console "URL Inspection" tool shows rendered HTML matching the user-visible page for at least the homepage, /business, and one localized page per target market
  • Schema validators (Schema.org validator + Google Rich Results Test) return no errors on the homepage and one localized page per target market
  • Page 1 SERP impressions for at least one "buy crypto + market" long-tail query within 60 days of market-page content shipping (tracked via Google Search Console)

Definition of Done

  • Code Produced (all todos completed)
  • Code Documented
  • Builds without errors
  • Unit Tests written and passing
  • Deployed to TEST environment and passed system tests
  • Remaining hours for tasks set to 0 and all tasks are closed

Additional Context

  • Affected surfaces: apps/frontend/index.html, apps/frontend/public/robots.txt, apps/frontend/public/sitemap.xml, Netlify configuration (netlify.toml if absent, must be created), apps/frontend/vite.config.ts (for SSG/SSR plugin), /terms-and-conditions source content, new locale route files under apps/frontend/src/pages/ per locale, i18n catalog expansion for es-AR, es-CO, es-MX, en-EU.
  • Tech constraints: Bun monorepo using React 19 + Vite + TanStack Router with i18n (currently en/pt-BR). Prerendering must be compatible with TanStack Router's route tree. Heavy deps (Polkadot.js, Wagmi, XState) drive bundle size — code-splitting needs to keep the marketing surface independent of the ramp widget bundle.
  • Recommended schema priorities:
    • Tier 1 (every page): Organization + FinancialService, WebSite + SearchAction (homepage only)
    • Tier 2 (market pages): FAQPage (primary AI-citation lever — Google restricted FAQ rich results to gov/health sites but GPTBot/ClaudeBot/PerplexityBot still parse and cite them heavily), Service per corridor, BreadcrumbList
    • Tier 3 (when content exists): Article / BlogPosting for educational corridor guides
    • Skip: HowTo (removed from Google rich results Sep 2023), SpecialAnnouncement (deprecated Jul 2025)
  • Demo plan: show before/after curl -sL <url> output for the homepage, /business, and /pt-BR/comprar-cripto-com-pix; show Google Search Console rendered HTML before and after; show Rich Results Test passing; show updated SEO Health Score; show first SERP impression in Google Search Console for any target-market keyword.
  • Out of scope (separate issues): content engine for /blog, link-building/PR strategy, aggregateRating schema integration with Trustpilot (once reviews accumulate), IndexNow integration for Bing/Yandex, Mexico (/es-MX/) market pages (covered by criteria but deferred to phase 2 since out of the May 21 target-market scope).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions