6 min read

The Canonical URL Is a System: Keeping Next.js, Vercel, and Sitemaps in Sync

What I learned from aligning a production hostname across Next.js metadata, redirects, robots, sitemaps, Open Graph data, and structured URLs.

Next.jsSEOVercelWebArchitecture

A canonical URL is easy to think about as one `<link rel="canonical">` tag. In a real application, that is only one signal among several. The same preferred hostname can appear in metadata, Open Graph fields, structured data, sitemaps, robots.txt, redirects, generated emails, and even project documentation.

I ran into this on my portfolio when the application was emitting a mixture of the apex domain, the `www` production hostname, and the Vercel project hostname. The pages could still load, but the system was describing more than one URL identity to crawlers and users. The fix was not a single metadata edit; it was a consistency pass across every place that generated or advertised a public URL.

Start with one source of truth

The first decision is surprisingly important: choose the exact public origin you want the application to advertise. For this portfolio, that is `https://www.techykaif.site`. Once that choice was made, I treated it as an application-level invariant rather than a page-specific preference.

In Next.js App Router projects, metadata can be defined centrally and then specialized per route. That makes the root metadata configuration a natural place to establish the base URL while still allowing individual pages to provide route-specific canonical paths, titles, and Open Graph fields.

  • Pick one production origin, including whether the preferred hostname is apex or `www`.
  • Use that origin for the application's metadata base.
  • Keep route-level canonical paths relative where the framework supports it.
  • Audit absolute URLs separately because they can bypass the centralized base.

Why redirects are not enough

Vercel can redirect one domain to another, and that is useful: visitors arriving at the non-preferred hostname can still reach the production site. But a redirect does not automatically fix every URL generated by the application. If a sitemap advertises the old hostname, an Open Graph object points at a different host, and structured data uses a third URL, the redirect is only one part of the story.

Google's canonicalization guidance treats redirects, canonical elements, and other technical signals as inputs to canonical selection. That is why I prefer to make the signals agree instead of relying on a redirect to compensate for inconsistent application output.

  • Redirects control where a request ends up.
  • Canonical metadata declares the preferred representation of a page.
  • Sitemaps provide a crawlable list of URLs the site considers important.
  • Structured data and Open Graph metadata can independently publish absolute URLs.

The sitemap and robots.txt need the same identity

The sitemap was one of the easiest places to miss because the routes themselves were already correct. The portfolio sitemap enumerates the blog index, individual articles, and project pages. Changing the sitemap base to the production hostname makes the discovery layer agree with the page metadata instead of sending crawlers to another host first.

The robots file has a similar responsibility: its sitemap declaration should point to the same preferred origin. This does not make a page index automatically, but it removes an avoidable source of disagreement about where the site's crawlable URL set lives.

Audit the less obvious absolute URLs

The most useful part of the cleanup was searching for absolute URLs rather than only reviewing SEO files. Project metadata, blog Open Graph objects, structured data, contact-email templates, README links, and other user-facing surfaces can all preserve an old hostname long after the main layout has been fixed.

That search also exposed why a centralized `metadataBase` is helpful but not sufficient. Relative URLs can inherit the base cleanly, while hard-coded absolute URLs remain independent. A domain migration or hostname preference change therefore needs both centralized configuration and a repository-wide audit.

  • Search source code for every old production hostname.
  • Check Open Graph `url` fields and JSON-LD URLs.
  • Check sitemap and robots output, not just their source files.
  • Check transactional emails and documentation for public links.
  • Verify redirects separately from generated application URLs.

Verification should test the public behavior

A text search is useful, but it is not the final verification. The important question is what a crawler or user actually receives. After the alignment, I verified that the preferred production host is the one emitted by the application and that the repository no longer intentionally generated the older production and Vercel hostnames in the affected surfaces.

For future changes, I would treat the public URL as a small contract: the preferred hostname should resolve, the alternate hostname should redirect predictably, page metadata should advertise the preferred origin, and the sitemap should enumerate the same origin. The exact checks can vary by hosting provider, but the invariant stays the same.

The broader lesson

SEO infrastructure is still infrastructure. A canonical URL is not just an HTML tag; it is a value that crosses application configuration, hosting, discovery, metadata, and content delivery boundaries. Bugs appear when those boundaries each have their own idea of what the production URL is.

The practical lesson from this cleanup is simple: choose the production URL once, make it easy to reuse, and then search for every place where an absolute URL can escape that source of truth. Consistency is the feature.