Speed & Technical SEO
This area covers page-level performance testing and on-page SEO editing: SpeedTest.tsx for Core Web Vitals and PageSpeed Insights (PSI) scoring, and OnPageEditor.tsx for editing meta tags, headings, content and structured data directly against a connected CMS, supported by the internal-linking and generate-meta-tags edge functions.
Speed Test & Core Web Vitals
SpeedTest.tsx lets a user test any URL (defaulting to the website's own domain) on mobile or desktop, invoking the speed-test edge function. While a test runs, an animated multi-step progress indicator walks through connecting, running the performance audit, checking accessibility, analysing best practices and calculating scores — reflecting that a full PageSpeed-style run typically takes 15–30 seconds.
Each completed test returns four 0–100 scores, shown as circular gauges: Performance, Accessibility, Best Practices and SEO — the same four categories Google's PageSpeed Insights/Lighthouse reports use. Performance is also labelled Fast (≥90), Average (≥50) or Slow.
Beneath the score gauges, individual Core Web Vitals and supporting metrics are shown as colour-coded cards (good / needs improvement / poor) against Google's published thresholds:
| Metric | Good | Needs improvement | Poor | |---|---|---|---| | First Contentful Paint (FCP) | ≤1800ms | — | >3000ms | | Largest Contentful Paint (LCP) | ≤2500ms | — | >4000ms | | Cumulative Layout Shift (CLS) | ≤0.1 | — | >0.25 | | Total Blocking Time (TBT) | ≤200ms | — | >600ms | | Speed Index (SI) | ≤3400ms | — | >5800ms | | Time to Interactive (TTI) | ≤3800ms | — | >7300ms |
Every test is stored in speed_tests and listed in a history table (date, device, key scores, LCP), so results can be recalled or deleted, and clicking a historical row reloads it into the main results view for comparison.
On-Page SEO Editor
OnPageEditor.tsx provides direct, field-level editing of a page or post's SEO metadata, backed by the onpage-editor edge function and a live CMS connection (WordPress or Shopify, via CMSConnectionWizard when none exists yet).
Workflow:
- List pages —
action: "list_pages"fetches the site's pages/posts (or products, on Shopify) from the connected CMS. - Fetch a page — selecting one calls
action: "fetch_page", returning title, meta description, canonical URL, robots directive, Open Graph title/description/image, H1/H2/H3 headings, image alt text, JSON-LD schema blocks, body HTML and word count. - Analyse —
action: "analyze", optionally scoped to a target keyword (which can be picked from the site's already-tracked keywords so published metadata lines up with what's ranking), returns a 0–100 score plus a per-field verdict (title tag, meta description, canonical URL, robots, Open Graph tags, H1, headings outline, body content, image alt text, JSON-LD schema) each flagged ok/needs-attention with an issue description and suggestion. - Auto-rewrite —
action: "rewrite"asks the AI to regenerate title, meta description, H1, Open Graph fields and schema markup around the target keyword in one pass; results are loaded into the editable fields for review before saving, not published automatically. - Suggest alt text —
action: "suggest_alt"generates alt text only for images that are currently missing it, keyed to the target keyword and page title, and merges suggestions into empty fields without overwriting existing alt text. - Save —
action: "update_page"writes title, meta description and body HTML back to the live CMS page.
The editor is organised into tabs (Meta, Headings, Content, Media & Schema) so title/description work, heading structure, body copy and structured data/alt text can each be reviewed independently before a single save.
Internal linking
The internal-linking edge function generates contextual internal link suggestions for a domain. It scrapes the site's homepage (respecting an internal isSafeUrl guard against fetching unsafe or internal network addresses), extracting the page title, meta description, H1/H2 headings and up to 20 existing internal links with their anchor text, then feeds that context to an AI model to propose new, relevant internal links — helping distribute authority between pages without a developer manually auditing the link graph.
Meta tag generation
generate-meta-tags follows the same scrape-then-generate pattern for a given domain (or specific pageUrl): it fetches the page, strips scripts/styles/nav/footer from the body, and extracts title, meta description, headings, Open Graph tags and keywords meta, then produces up to ~2000 characters of visible body text as context for the AI. This grounded context means generated titles and meta descriptions reflect the page's actual content and existing on-page signals rather than being generated blind from the domain name alone.
Access and safety
Both internal-linking and generate-meta-tags require an authenticated user and reject requests targeting unsafe or internal URLs before making any outbound fetch. Speed testing and the On-Page Editor are gated where relevant by the website's plan (the On-Page Editor also requires an active WordPress or Shopify connection before it can list or edit pages).