The proxy moved the page. The canonical tag did not.
A reverse proxy changes the address a page is served from. It does not change the HTML, so the canonical tag keeps naming wherever the platform thinks it lives: yoursite.webflow.io, a .framer.website address, or the old blog subdomain. The fix is one setting on the platform, not a rule in the proxy.
Published October 2, 2026. Platform settings and Google documentation checked the same day.
The short answer
Every proxied page should declare its own public URL as canonical. Out of the box, most do not: the platform writes the tag from its own hostname, and the proxy passes it through untouched.
Google lists rel="canonical" as a strong canonicalization signal, so a tag naming the origin host is a strong signal pointed the wrong way. Webflow, Framer, and WordPress each have a setting that corrects it at the source. Set it, republish, then confirm with a view source and Search Console's URL Inspection.
same html, two addresses: the tag picks which one collects the links
Why does a reverse proxy break canonical tags?
Because the tag is generated before the proxy is involved. A platform builds <link rel="canonical"> from the domain it believes it is connected to. With a proxy in front, your public domain points at the proxy, not at the platform, so the platform has no way to know the address visitors actually see.
Framer's documentation states this directly: when a site is served through a reverse proxy and the domain is not connected to the project, Framer cannot determine the correct domain, and its SEO tags may default to the .framer.website domain. The same logic applies to any platform that derives the tag from its own settings.
What that costs depends on how Google resolves it. Its canonicalization overview describes a declared canonical as a hint, not a rule, so Google can still settle on your public URL. It can also take the tag at its word and treat the origin hostname as the representative version, which is the outcome the proxy was built to avoid. This is not a spam-policy problem: Google says some duplicate content on a site is normal. The risk is plainer than that. The wrong URL shows in results, and links get consolidated onto a host you did not choose.
Where do you fix it on each platform?
At the origin, in the one setting that tells the platform its public address. All three below are documented by the platforms themselves.
Webflow
Site settings > SEO > Global canonical tag URL
Webflow combines this base URL with each page’s slug to build every canonical tag. Its help center says the value should normally match your default domain, and names a reverse proxy setup as the case where you may need a different one. Include https:// and www if you use it, and leave off the trailing slash, or every subpage canonical gets a double slash. Publish for it to take effect.
Framer
Settings > Domains > Canonical URL
Framer builds its SEO tags from the connected domain. Behind a proxy it cannot see your public domain, and its docs say the tags may default to the project’s .framer.website address. Enter the public URL, including the path when Framer is one section of a larger site (https://yourdomain.com/blog), then republish. Framer’s proxy guide lists the Canonical URL as available with its Advanced Hosting add-on.
WordPress
Settings > General > Site Address (URL), or WP_HOME
Core WordPress builds the canonical from the post’s permalink, and the permalink starts from the Site Address. Set it to the public path (https://yourdomain.com/blog) and the tag follows. Core only outputs a canonical on singular pages such as posts and pages; archives and the blog index get one only if a theme or SEO plugin adds it, so check those templates separately.
WordPress detail for engineers: the Site Address is the address people type to reach the site, and it can be pinned in wp-config.php:
define( 'WP_HOME', 'https://yourdomain.com/blog' );Once the constant is defined, the field in the admin screen is locked to that value. Changing the Site Address also changes every permalink WordPress generates, so try it on the preview route before the public one.
Which signals have to agree with the tag?
Four of them. Google's canonicalization methods documentation ranks redirects, canonical annotations, and sitemap inclusion by how strongly they influence the choice, says they become more effective when combined, and warns against naming different URLs for the same page through different techniques. A proxied section is where they drift apart, because each one is generated by a different system.
Redirects
Strong signal
If the content used to live on a public subdomain, every old URL permanently redirects to its subfolder URL. Not relevant when the origin hostname was never public.
rel="canonical"
Strong signal
Every proxied page names its own public URL, in absolute form: https://yourdomain.com/blog/post-name. This is the one the proxy quietly gets wrong.
Sitemap inclusion
Weak signal
The sitemap lists public subfolder URLs only. A sitemap generated by the origin platform can still list origin hostnames, so open it and read the first few entries.
Internal links
Best practice
Navigation, body links, and og:url point at the public URLs. Google says linking consistently to the URL you consider canonical helps it understand your preference.
What about the origin hostname that still serves the same pages?
Leave it reachable and let the canonical do its job. The proxy has to fetch from somewhere, so the origin hostname keeps answering with the same HTML. Once the platform setting is corrected, that copy carries the same tag naming your public URL, which is exactly the situation the canonical tag exists for.
The two tempting shortcuts are the ones Google's documentation rules out. It says not to use robots.txt for canonicalization, since blocked URLs can still be indexed without their content, and it does not recommend noindex for steering canonical selection within a site, since it blocks the page from Search completely. Behind a proxy that second one bites harder. The origin and the public URL serve the same HTML, so a noindex switched on at the platform is delivered on yourdomain.com/blog too.
Framer's reverse proxy guide makes the same point from the platform side: it tells you not to proxy from a framer.app address, because those domains are not indexed by search engines and using one as the origin will hurt SEO.
The exception is a hostname that used to be public, such as blog.yourdomain.com. That one gets page-level permanent redirects to the subfolder, which Google describes as the method for deprecating a duplicate, while the proxy fetches from a separate origin address.
How do you verify the canonical is right?
Start from the command line, because it shows what a crawler receives rather than what a browser extension reports:
curl -s https://yourdomain.com/blog/post-name | grep -io '<link[^>]*rel="canonical"[^>]*>'- 1
Read the tag on the public URL
Fetch a proxied page and look at what it declares. Check a post, a listing page, and the section home, because platforms build these from different templates.
- 2
Count the tags
There should be exactly one canonical per page. Webflow’s documentation warns that injecting a second one through another tool creates multiple canonical tags, which search engines may ignore entirely.
- 3
Fetch the same page on the origin hostname
It should declare the same public URL as the proxied copy. If the origin copy names itself, you have two pages each claiming to be the original.
- 4
Compare declared and selected in Search Console
URL Inspection shows the User-declared canonical next to the Google-selected canonical. Google notes that only the indexed data shows this; the live test cannot predict which version will be chosen.
- 5
Give it time before judging
Google’s troubleshooting documentation says pages can stay in a duplicate cluster for up to two weeks after a fix. Request indexing for the handful of URLs that matter most; the feature has quotas.
Field names and timing are from Google's URL Inspection reference and its canonicalization troubleshooting guide. One caveat on scope: curl only sees a tag that is in the HTML source. If your platform injects the canonical with JavaScript, the command comes back empty and Search Console is the check that counts.
Should the proxy rewrite the tag instead?
Only as a last resort. Rewriting HTML in flight is possible on most edge platforms, and it is the usual first instinct of whoever built the proxy. It also means your canonical now depends on a string replacement that has to survive every template change on the origin, and it leaves the origin hostname's own copy declaring itself.
Some platforms rule it out. Framer lists reverse proxy setups that modify or remove tags in <head> as unsupported, because its own JavaScript manages some of them. Adding a Link response header at the proxy is not a clean escape either: Google supports the header, but recommends choosing one method, since using the header and the element together is more error prone.
So the order is: set the platform's canonical setting, and reach for rewriting only when the platform offers none. Whoever runs your proxy, ask what it does to the HTML it forwards. That question applies to a managed service like ours as much as to a worker script, and the curl check above answers it in ten seconds either way.
Canonical tags and proxies: FAQs
Does a reverse proxy change canonical tags automatically?
No. A reverse proxy changes the address a page is served from, not the HTML inside it. The canonical tag is written by the origin platform from its own idea of where it lives, so unless you change that setting, the proxied page keeps declaring the origin hostname as canonical.
What should the canonical tag say on a proxied page?
The public URL the visitor sees, in absolute form with https, for example https://yourdomain.com/blog/post-name. Google recommends absolute rather than relative URLs in canonical tags and recommends a self-referential canonical on the canonical page itself.
Will Google ignore a wrong canonical and pick the right URL anyway?
It might, but you should not plan on it. Google describes a canonical preference as a hint, not a rule, and lists rel="canonical" as a strong signal. A tag pointing at the origin host is a strong signal in the wrong direction, competing with whatever else you have set up.
Should I noindex or block the origin hostname in robots.txt?
Google advises against both for canonicalization. It says not to use robots.txt for canonicalization purposes, and does not recommend noindex for choosing a canonical because it removes the page from Search completely. Behind a proxy, a noindex added at the origin is also served on your public URL, since both come from the same HTML.
Can I add the canonical as an HTTP header at the proxy instead?
Google supports a rel="canonical" Link header, but it recommends choosing one method, because using the header and the HTML element together is more error prone. If the origin still emits a tag naming the origin host, a header naming the public URL gives Google two different answers. Fix the tag at the platform.