Skip to content

Notion client overwrites canonical URL and og:url in the browser #193

Closed

Description

@shigahi

Summary

After the Notion client loads, it rewrites <link rel="canonical"> and og:url to its own /<Title>-<page-id> path. This happens on every page, including the home page, and replaces the values the worker set. og:url becomes a relative path, which isn't valid for Open Graph (it must be an absolute URL).

The client script already keeps the configured title and description (applyMeta, #146), but not these two tags.

Observed (2026-10-28)

Render check page in wrangler dev, read in Chromium 10 s after load. The result was the same with the worker before and after #192:

Path Worker's canonical (server HTML) After the client loads
/ https://render-check.example.com canonical https://render-check.example.com/Worknot-Render-Check-3e6558d7de1781bb89a9fb6adc4012d6, og:url /Worknot-Render-Check-3e6558d7de1781bb89a9fb6adc4012d6
/3e6558d7de1781258e84de9616a91c0e (no slug) https://render-check.example.com/3e6558d7de1781258e84de9616a91c0e (#192) canonical https://render-check.example.com/Item-Beta-3e6558d7de1781258e84de9616a91c0e, og:url relative

Impact

Since #191, crawlers that don't run JavaScript get the server-rendered page, so they see the worker's canonical URL. The client's values still reach:

  • crawlers and tools that render JavaScript but don't match the worker's crawler pattern, such as Google-InspectionTool and SEO auditors that use a Chrome user agent;
  • Googlebot and Bingbot, if they are ever excluded from the crawler pattern again (see the decision in Serve Notion's server-rendered pages to crawlers #191);
  • anything that reads the tags from the live page, such as share buttons and browser extensions.

On the home page, the canonical URL then points to /Worknot-Render-Check-<id>, while the server HTML for that URL names / as canonical. These are conflicting signals for the same page.

Proposed Solution

  • In the client script, keep link[rel=canonical] href, og:url and twitter:url on the worker's canonical URL. Compute it the same way as the server: https://<domain>/<slug> for mapped pages, https://<domain>/<page-id> for pages without a slug (Give pages without a slug their own canonical URL #192), and the bare domain for the home page.
  • Watch href as well as content in the existing head MutationObserver (attributeFilter), and recompute on client-side navigation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: seoSEO related featuresbugSomething isn't workingpriority: lowFuture consideration

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions