Search & discovery
Canonical URL Manager
Generated from docs/plan/core/canonical-url-manager/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
Canonical URL Manager is a core feature that lets merchants set canonical URLs on products and pages. It prevents Google from penalizing duplicate content across URL variations.
The problem
Merchants have duplicate content across URL variations; Google penalizes them for duplicate pages.
What it does
- Provide UI field for custom canonical URL on product/page edit forms
- Auto-generate canonical URL if merchant doesn’t set custom (default to primary URL)
- Support self-referential canonicals (product URL points to itself) and cross-domain canonicals
- Render <link rel=‘canonical’ href=’…’> tag in HTML head
- Admin bulk canonical URL editor and validation warnings
- Copy canonical from one product to similar products (template feature)
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- Does NOT handle URL parameter canonicalization (reason: HTTP server config, not CMS)
- Does NOT track canonical effectiveness (reason: requires Google Search Console API)
- Does NOT generate canonical URLs from URL patterns (reason: separate feature, requires complexity)
Data model
New fields on products: canonical_url (string, optional). Same field on pages.
API
- PATCH /api/products/:id {canonical_url}
- PATCH /api/pages/:id {canonical_url}
- GET /api/products/:id/canonical
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Product edit form with canonical URL field and validation; warning icon if different domain or appears wrong; bulk editor for multi-select products; reset button to revert to auto-generated.
The seam — why this is core
Core owns: canonical storage, rendering in HTML head, validation.
Core owns the interface + honest editor; canonical tags are SEO metadata, not a support commitment or per-country obligation.
Dependencies
- Assumes product/page API exists
- Assumes render engine can access canonical_url field
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- Custom canonical URL is rendered in <link rel=‘canonical’> tag
- If canonical_url is empty, fallback is product’s primary URL
- Canonical URL must be valid HTTP/HTTPS URL or validation fails
- Warning appears if canonical domain differs from site domain
- Merchant can set canonical to external URL (for syndicated products)
- Bulk editor updates canonical for 100 products in one request
- All storage drivers support canonical_url field equally
Risks
Merchant sets wrong canonical: product never indexed because canonicalized to competitor. Cross-domain canonicals may be ignored by Google if domain not verified in Search Console. Schema migration adding canonical_url field.
Commercial context
| Suggested price | free (core) |
| Rival anchor | Shopify: included; Magento: included |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.