# og:url matches the page canonical URL

- **Pattern:** `ab-001808` (`marketing-social-sharing.open-graph.og-canonical-match`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001808
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001808)

## Why it matters

Without og:url, social platform crawlers cannot reliably deduplicate shares of the same page that arrive via different URLs — such as with UTM parameters, trailing slashes, or HTTP vs HTTPS variants. Per ogp.me, og:url specifies the canonical URL that should aggregate all social engagement signals. When og:url is absent or mismatched with the canonical URL, share counts and engagement metrics fragment across URL variants. This directly affects how platforms surface your content in social feeds and how link preview analytics attribute engagement. The findability impact is concrete: a page shared 500 times across two URL variants may show as two separate posts with 250 shares each rather than one high-engagement result.

## Severity rationale

High because a missing or mismatched og:url fragments social engagement metrics across URL variants, reducing apparent post engagement and undermining SEO deduplication signals.

## Remediation

Set og:url alongside your other OG properties and keep it in sync with your canonical URL. Both should use the same scheme, host, and path:

```ts
export async function generateMetadata({ params }): Promise<Metadata> {
  return {
    alternates: { canonical: `https://yoursite.com/blog/${params.slug}` },
    openGraph: {
      url: `https://yoursite.com/blog/${params.slug}`,
      title: post.title,
      description: post.excerpt,
      images: [...],
    },
  }
}
```

For static pages, set both `metadata.alternates.canonical` and `metadata.openGraph.url` in the page's `metadata` export. If you use a `NEXT_PUBLIC_SITE_URL` environment variable for the base, apply it consistently to both fields.

## Detection

- **ID:** `og-canonical-match`
- **Severity:** `high`
- **What to look for:** Check whether `og:url` is set and, where determinable, matches the canonical URL for that page. In Next.js App Router, look for `metadata.openGraph.url` alongside `metadata.alternates.canonical`. For dynamic routes using `generateMetadata`, check that both `openGraph.url` and `alternates.canonical` are set using the same base URL and path pattern. Count all instances found and enumerate each.
- **Pass criteria:** `og:url` is set on pages that have OG tags. Where both `og:url` and canonical are set, they point to the same URL. If `og:url` is absent but the OG block is otherwise complete, this check fails — the `og:url` field is required for proper deduplication by social crawlers. At least 1 implementation must be confirmed.
- **Fail criteria:** `og:url` is missing from pages that have other OG tags, OR `og:url` and the canonical URL point to different URLs on the same page.
- **Skip (N/A) when:** No OG tags found anywhere in the project (caught by `og-all-pages-complete`).
- **Detail on fail:** `"og:url not set in metadata.openGraph configuration — social crawlers cannot deduplicate shares of the same page"` or `"og:url uses HTTP while canonical uses HTTPS on /blog/[slug] pages"`
- **Remediation:** `og:url` tells social platforms the canonical URL for a shared page. Without it, the platform may attribute shares of the same page to different URLs (e.g., with vs. without query parameters). Set it alongside your other OG tags:

  ```ts
  export async function generateMetadata({ params }): Promise<Metadata> {
    return {
      alternates: { canonical: `https://yoursite.com/blog/${params.slug}` },
      openGraph: {
        url: `https://yoursite.com/blog/${params.slug}`,
        title: post.title,
        description: post.excerpt,
        images: [...],
      },
    }
  }
  ```

## External references

- external ogp.me — https://ogp.me/

Taxons: findability

HTML version: https://auditbuffet.com/patterns/ab-001808
