Generate a canonical link tag from any valid HTTP URL
The canonical link tag generator turns one absolute web address into a ready-to-paste HTML link element for the head of a page.
Run — free
It validates that the address can be parsed and that it uses HTTP or HTTPS, then safely escapes the value for an HTML attribute. The result includes both the normalized canonical URL and the complete tag, making it useful for a quick manual edit, a publishing workflow, a template system, or an automated SEO pipeline.
Choose the URL that represents the preferred page
A canonical tag tells search engines which absolute URL you consider the preferred version of a page. Start with the address that should remain authoritative when the same content is reachable through tracking parameters, alternate navigation paths, print views, or other duplicates. Include the scheme and hostname, because a relative path such as /guides/example does not identify one unambiguous page across sites. Choose HTTP or HTTPS explicitly; in most production cases, use the HTTPS address that visitors and crawlers can load. Preserve meaningful paths, query parameters, and fragments only when they truly belong in the preferred address. This generator parses the supplied value and serializes it consistently, so details such as an omitted root slash or an internationalized hostname may appear in normalized URL form. It does not visit the page, test redirects, compare duplicate content, or decide which variant deserves canonical status. That editorial decision stays with you. Before generating the tag, confirm that the destination is public, stable, indexable, and intended to be the long-term reference for the content.
Generate safe markup for the document head
Submit the chosen address in the url field. The tool removes surrounding whitespace, verifies that the value is an absolute URL, and accepts only the http and https schemes. Addresses using mailto, ftp, javascript, file, or a custom application protocol are rejected because they cannot serve as conventional web canonicals. A successful result contains canonical_url, which shows the URL after standard parsing, and tag, which contains the complete link element. The href value is escaped for a double-quoted HTML attribute, including ampersands in query strings, so the markup can be inserted without accidentally turning URL characters into HTML syntax. Place the generated element inside the page's head, normally once per document. Do not add a second competing canonical declaration in the HTML, and make sure an HTTP response header or framework plugin is not publishing a different target. The generator deliberately produces a concise HTML tag without a closing slash because link is a void element in HTML. It generates markup only and does not modify any page or contact any server.
Verify deployment and keep canonicals consistent
After adding the generated tag, inspect the rendered page source or your framework's final server response rather than checking only a template file. Content management systems, SEO plugins, themes, and rendering middleware can replace, duplicate, or remove head elements after your edit. Confirm that exactly one intended canonical link is present and that its href matches the public URL you selected. Then test the destination in the environment where it will be published: it should resolve successfully, avoid an unnecessary redirect chain, and not be blocked from indexing if search visibility is the goal. Apply the same policy consistently across pagination, filtered collections, localized pages, mobile variants, and parameterized campaign URLs. Canonical tags are hints for consolidating equivalent pages, not redirects and not access controls, so users can still open every variant. When a preferred URL changes, regenerate the tag and update internal links, sitemaps, redirects, and structured data where appropriate. For automation, the API costs $0.002 per request; the browser version lets you produce the same deterministic output locally for quick one-off work.
What you can do with it
Prepare a tag for a CMS template
Turn the preferred article URL into escaped markup that can be pasted into a document head or template field.
Normalize tags in a publishing pipeline
Generate a consistent canonical URL and link element before pages are assembled and deployed.
Handle parameterized URLs safely
Create valid HTML when a canonical address contains query parameters whose ampersands require attribute escaping.
FAQ
What input does the generator accept?
It accepts one absolute URL with an http or https scheme and a hostname. Relative paths and other protocols are rejected.
Does the tool check whether the page exists?
No. It performs deterministic syntax and protocol validation without making network requests.
Why are ampersands shown as & in the returned tag?
The URL is escaped for safe use in an HTML attribute. A browser interprets that markup as an ampersand in the actual URL.
Where should I place the generated tag?
Place it inside the HTML head and avoid publishing another canonical tag with a conflicting URL.
How much does the API request cost?
Each API request costs $0.002. The in-browser generator is available for one-off use.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/web/canonical-tag-generate \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/articles/canonical-tags?edition=web"}'const res = await fetch("https://api.kit.forhosting.com/web/canonical-tag-generate", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"url": "https://example.com/articles/canonical-tags?edition=web"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/web/canonical-tag-generate",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"url": "https://example.com/articles/canonical-tags?edition=web"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/web/canonical-tag-generate", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"url":"https://example.com/articles/canonical-tags?edition=web"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"url":"https://example.com/articles/canonical-tags?edition=web"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/web/canonical-tag-generate", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"url": "https://example.com/articles/canonical-tags?edition=web"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "web.canonical_tag_generate",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
timeout_sec | 30 |
max_crawl_pages | 25 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |