---
title: "Canonical Plugin"
description: "Fix relative URLs in your meta tags automatically for better SEO"
navigation.title: "Canonical Plugin"
---
**Quick Answer:** The Canonical plugin automatically generates `` tags and converts relative URLs to absolute URLs in your meta tags. Enable it with `CanonicalPlugin({ canonicalHost: 'https://mysite.com' })` in your head configuration.
## Why Do I Need Absolute URLs in Meta Tags?
The Canonical Plugin automatically converts relative URLs to absolute URLs in your meta tags, which is essential for:
- [Google SEO](https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls): Requires absolute URLs for canonical links
- [Facebook](https://developers.facebook.com/docs/sharing/webmasters/getting-started): Ignores relative image paths in Open Graph tags
- [Twitter](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup): Requires absolute URLs for Twitter Card images
## What Tags Does the Plugin Transform?
The plugin transforms these tags automatically:
- `og:image` and `twitter:image` meta tags
- `og:url` meta tag
- `rel="canonical"` link tag
::code-block
```html [Before]
```
```html [After]
```
::
## How Do I Set Up the Canonical Plugin?
Install the plugin in both your server & client entries:
::code-block
```ts [Input]
import { CanonicalPlugin } from 'unhead/plugins'
const head = createHead({
plugins: [
CanonicalPlugin({
canonicalHost: 'https://mysite.com'
})
]
})
```
::
## What Are the Configuration Options?
::code-block
```ts [Input]
interface CanonicalPluginOptions {
// Your site's domain (required)
canonicalHost?: string
// Optional: Custom function to transform URLs
customResolver?: (path: string) => string
}
```
::
### What Happens If I Don't Set canonicalHost?
- If no `canonicalHost` is provided:
- Client-side: Uses `window.location.origin`
- SSR: Leaves URLs as-is (relative)
::tip
Always set `canonicalHost` explicitly for consistent behavior across environments.
::
### How Do I Customize URL Resolution?
Use `customResolver` to implement custom URL transformation logic:
::code-block
```ts [Input]
CanonicalPlugin({
canonicalHost: 'https://mysite.com',
customResolver: path => new URL(`/cdn${path}`, 'https://example.com').toString()
})
```
::
Example transformation:
::code-block
```html [Before]
```
```html [After]
```
::
## How Do I Integrate with a CDN?
Point image assets to your CDN domain:
::code-block
```ts [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}`
}
})
```
::
## Related
- [Template Params](/docs/head/guides/plugins/template-params) - Dynamic template parameters
- [Infer SEO Meta](/docs/head/guides/plugins/infer-seo-meta-tags) - Auto-generate SEO tags