TypeScript

Canonical Plugin

Introduction

The Canonical Plugin automatically converts relative URLs to absolute URLs in your meta tags, which is essential for:

  • Google SEO: Requires absolute URLs for canonical links
  • Facebook: Ignores relative image paths in Open Graph tags
  • Twitter: Requires absolute URLs for Twitter Card images

How It Works

The plugin transforms these tags automatically:

  • og:image and twitter:image meta tags
  • og:url meta tag
  • rel="canonical" link tag
Before
<meta property="og:image" content="/images/hero.jpg">
After
<meta property="og:image" content="https://mysite.com/images/hero.jpg">

Setup

Install the plugin in both your server & client entries:

Input
import { CanonicalPlugin } from 'unhead/plugins'

const head = createHead({
  plugins: [
    CanonicalPlugin({
      canonicalHost: 'https://mysite.com'
    })
  ]
})

Configuration

Input
interface CanonicalPluginOptions {
  // Your site's domain (required)
  canonicalHost?: string
  // Optional: Custom function to transform URLs
  customResolver?: (path: string) => string
}

Fallback Behavior

  • If no canonicalHost is provided:
    • Client-side: Uses window.location.origin
    • SSR: Leaves URLs as-is (relative)
Always set canonicalHost explicitly for consistent behavior across environments.

Custom URL Resolution

Use customResolver to implement custom URL transformation logic:

Input
CanonicalPlugin({
  canonicalHost: 'https://mysite.com',
  customResolver: path => new URL(`/cdn${path}`, 'https://example.com').toString()
})

Example transformation:

Before
<meta property="og:image" content="/hero.jpg">
After
<meta property="og:image" content="https://mysite.com/cdn/hero.jpg">

Common Use Cases

CDN Integration

Point image assets to your CDN domain:

Input
CanonicalPlugin({
  canonicalHost: 'https://mysite.com',
  customResolver: (path) => {
    // Send image paths to CDN, keep other URLs on main domain
    if (path.match(/\.(jpg|png|webp|gif|svg)$/i))
      return `https://cdn.mysite.com${path}`
    return `https://mysite.com${path}`
  }
})
Did this page help you?