{"section":"known-issues","requestedLocale":"en","requestedSlug":"canonical-link-keeps-the-trailing-slash-of-the-requested-url-on-routes-declared-in-the-themes-routesjson","locale":"en","slug":"canonical-link-keeps-the-trailing-slash-of-the-requested-url-on-routes-declared-in-the-themes-routesjson","path":"docs/en/known-issues/Store Framework/canonical-link-keeps-the-trailing-slash-of-the-requested-url-on-routes-declared-in-the-themes-routesjson.md","branch":"main","content":"## Summary\n\nOn Store Framework pages whose route is declared only in the theme’s `store/routes.json` (no `canonical` set), the `<link rel=\"canonical\">` is built from the URL that was requested, trailing slash included. Both `/my-page` and `/my-page/` return 200 and each declares itself as canonical:\n\n- `/my-page` returns `<link rel=\"canonical\" href=\"https://store.example.com/my-page\"/>`\n- `/my-page/` returns `<link rel=\"canonical\" href=\"https://store.example.com/my-page/\"/>`\n\nThe canonical therefore does not consolidate the two URLs, and search engines may index them as duplicates. Product and category pages are not affected (their canonical is normalized without the slash).\n\n## Simulation\n\n1. In a Store Framework theme, declare a route in store/routes.json without a `canonical`, for example\n\n2. Publish and open the page.\n3. Request the page without and with a trailing slash and read the canonical tag: `curl -s https://<store>/my-page | grep -o '<link[^>]*rel=\"canonical\"[^>]*>'` and `curl -s https://<store>/my-page/ | grep -o '<link[^>]*rel=\"canonical\"[^>]*>'`.\n4. Expected: the same canonical for both (without the trailing slash). Actual: each response echoes the requested path.\n\n## Workaround\n\nDeclare the route in the theme’s `store/routes.json` with an optional trailing slash in `path` and an explicit `canonical` without it:\n\n```\n\"store.custom#my-page\": { \"path\": \"/my-page(/)\", \"canonical\": \"/my-page\" }\n```\n\n\nWith this, both `/my-page` and `/my-page/` return 200 and declare `https://store.example.com/my-page` as canonical. Setting `canonical` equal to `path` is rejected by the build, which is why the optional `(/)` is needed."}