Skip to content

fix(seo): consolidate versioned library landing pages onto /latest #1150

Description

@KevinVandy

Problem

The recent latest-version redirect work correctly handles documentation routes, but product-specific landing routes bypass the shared /_library/$libraryId/$version parent.

Live examples currently returning 200 with self-referencing canonicals:

  • /query/v5 and /query/latest
  • /router/v1 and /router/latest
  • /ai/v0 and /ai/latest

This leaves duplicate landing pages even though nested latest-version docs correctly return 308.

The product-specific routes call beforeLoadLibraryLanding in src/routes/-library-landing-route.tsx. That helper validates a version but does not redirect library.latestVersion to latest. The current latest-version check in src/routes/_library/$libraryId/$version.tsx does not govern these static landing routes.

Google canonical guidance: https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls

Desired behavior

  • /{library}/{library.latestVersion} permanently redirects with 308 to /{library}/latest.
  • Preserve the remainder of the request URL where applicable, including meaningful search parameters.
  • Every indexable library landing page, including historical numbered landing pages that remain accessible, declares /{library}/latest as its canonical landing URL.
  • og:url and twitter:url match the /latest canonical.
  • No numbered library landing page self-canonicalizes.
  • Existing historical documentation behavior remains unchanged: historical docs may remain accessible and use their current path-aware canonical logic.

Acceptance criteria

  • The shared product landing helper enforces the latest-numbered-version redirect for every product-specific landing route.
  • Tests cover at least Query, Router, AI, and one library with non-v1 latestVersion metadata.
  • /query/v5, /router/v1, and /ai/v0 return 308 to their /latest equivalents in an integration test.
  • Historical landing pages that return 200 emit only one canonical link, pointing to /latest.
  • /latest landing pages self-canonicalize and remain 200.
  • Sitemap entries continue to contain only /latest library landing pages.
  • Stable unversioned aliases such as /query are reviewed and use a permanent redirect when their mapping to /latest is intentional.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions