Skip to main content

SEO Indexing — Web Implementation Plan

This directory contains the full, step-by-step implementation plan for SEO Indexing on the RecordPlus Web product (record-web). It maps directly to the SEO Indexing PRD.

These documents are written to be executed by an engineer or an AI coding agent with no prior context on this feature. Every task references real files, real patterns already in the codebase, and exact code to add. Follow them in order.


Phase index

PhaseFileGoalBlocking external deps
Phase 1PHASE-1-CRAWLABILITY.mdPublic detail HTML crawlable, protected and technical HTML noindex, valid concrete detail sitemap URLs, metadataBase, pt-BR, and verification support.Concrete catalogue enumeration is required only for a future catalogue-complete sitemap.
Phase 2PHASE-2-METADATA-CANONICALS.mdCanonical URLs on every indexable page, complete OG + Twitter tags, per-asset title/description/image on detail pages.Phase 1 merged.
Phase 3PHASE-3-STRUCTURED-DATA.mdSafe JSON-LD only on pages whose rendered playback experience and JWX data satisfy the applicable eligibility rules.OQ-2 JWX fields, OQ-4 Live policy, and logged-out watch-page decision.
Phase 4PHASE-4-CORE-WEB-VITALS.mdBaseline CWV measurement, hero image / CLS / font / bundle fixes to reach "mostly green" on all indexable page types.Phase 1 live in production (≥ 28 days CrUX data).
MiddlewarePHASE-5-MIDDLEWARE-SEO-ENABLEMENT.mdJWX catalogue feed, real modification data, availability, scale, and optional JWX-driven freshness.Feed is a launch dependency when catalogue-complete discovery is required; other enhancements are conditional.

Provider note: Record uses JWX. Do not extend the legacy Brightcove webhook path for new SEO work. A middleware companion document does not exist yet; create it with the JWX implementation ticket rather than linking to a nonexistent file.


Architecture cheat-sheet (read once before starting)

record-web is a Next.js 16.2 App Router application (src/app/). The conventions you must follow:

  • Primary dynamic route: src/app/[[...routeSegments]]/page.tsx — catch-all that resolves the CMS page via getDynamicRoutes() + getViewFromPage() from routeToViewMapper.ts.
  • Page-type → component mapping: src/views/routeToViewMapper.ts maps CMS pageType strings to React view components and their generateMetadata functions. Detail pages (MovieDetailsPage, ShowDetailsPage) live in src/views/*/.
  • Metadata utility: src/utils/metadata.tsbaseMetadata object and getMetadata() helper. All pages should build on getMetadata(), not construct raw Metadata objects.
  • Sitemap: src/app/sitemap.ts — Next.js MetadataRoute.Sitemap export, calls getDynamicRoutes() for CMS-managed routes.
  • Robots: src/app/robots.ts — Next.js MetadataRoute.Robots export.
  • Root layout: src/app/layout.tsx — exports the metadata constant (root defaults) and the revalidate constant (ISR cache window, from env DEFAULT_CACHE_REVALIDATION).
  • ISR/SSR: Next.js App Router serves SSR by default. Server Components fetch data at request time (or from the Next.js cache). revalidate at segment level controls ISR.
  • CMS SEO fields: pages provide page.seo?.metaTitle, page.seo?.metaDescription, page.seo?.metaKeywords. Asset metadata comes from the OVP provider via ServiceManager.getServiceProvider('ovp').

Indexable pages (confirmed Web scope)

Page typeCMS template / routeIndexable
Movie DetailMovieDetailsPage
Show/Series DetailShowDetailsPage
Podcast DetailPodcastDetailsPage
Radio Detailconfigured detail route
Channel Detailconfigured detail route
Other supported detailsconfigured detail route
HomeModular
Category and ListingModular
Search results/search
My List/my-list
Your Region/your-region
Billing and payment success/billing/*, /payment/*/success
Technical CMS page/page/*
View All query surface/view-all
Profile/profile
Player/player
Payment/payment
Subscription/subscription
Signup/signup
Account/account
Login/login
EPG/epg

Signed-out users and crawlers receive the same access result. Detail pages are public; non-detail application entry points redirect to Login.

Open questions that gate work (resolve before the relevant phase)

IDQuestionBlocks
OQ-2JWX exposes uploadDate, duration, thumbnailUrl, description for VideoObject / TVSeries?Phase 3
OQ-4Live event pages indexed during live window, post-VOD, or both?Phase 3 (Live JSON-LD)
Brand nameExact product brand string to replace "Assemble Web" defaultsPhase 1 Task 7

Definition of done (per phase)

A phase is "done" when:

  1. pnpm build succeeds with no TypeScript errors.
  2. Unit tests for new utilities pass (pnpm test).
  3. The manual QA checklist at the end of that phase passes.
  4. /code-review skill reports no BLOCKERs.