Your Canonical Says webight.com. Your Server Says www. Google Sees 2 Sites. I Had This Exact Bug Yesterday.
Type your domain into the browser without www. Now type it with www. Both load, right? Good. To you that's one website. To Google, those can be 2 separate...
Garvit Sharma
11 June 2026 · 6 MIN READ
Your Canonical Says webight.com. Your Server Says www. Google Sees 2 Sites. I Had This Exact Bug Yesterday.
webight.comOn this page
Type your domain into the browser without www. Now type it with www. Both load, right? Good. To you that's one website. To Google, those can be 2 separate sites competing against each other for the same keywords, splitting every link and every ranking signal between them.
I shipped this exact bug on my own studio's site. Found it yesterday while running a full audit on webight.com. The canonical tag on every page said https://webight.com. The server had a different opinion. Hit webight.com and it answered with a 307 redirect to https://www.webight.com. So every page was telling Google "the real version of me lives on the apex domain" while the apex domain refused to serve anything and pushed everyone to www.
Two signals, pointing in opposite directions. And here's the part that should bother you: Lighthouse gave that site a 100 on SEO while this was live. The audit scores before I touched anything were 90, 96, 96, 100 for performance, accessibility, best practices, and SEO on mobile. A perfect SEO score, with canonicals pointing at a host the server would not serve. Lighthouse checks the page it loads. It does not compare your canonical tag against your redirect rules. Nothing in your build pipeline does. That's why this bug survives on so many production sites.
One big idea today: your site has exactly one address, and every layer of your stack has to agree on what it is. The redirect, the canonical, the sitemap, the Open Graph URLs, the structured data. All of them. When they disagree, Google stops trusting your hints and picks a winner for you. Sometimes it picks wrong.
What a canonical actually does
The canonical is one line in your <head>:
<link rel="canonical" href="https://www.webight.com" />
It is your vote for which URL is the official one when the same content is reachable at multiple addresses. And your homepage is always reachable at multiple addresses. Count them: http://webight.com, https://webight.com, http://www.webight.com, https://www.webight.com. Four URLs, one page. Google calls these a duplicate cluster and picks one canonical URL for the whole cluster, then funnels all ranking signals into that one.
See, the canonical tag is a hint, never a command. Google's own docs say this. When your hint agrees with your redirects, your sitemap, and your internal links, Google takes it. When your canonical says apex and your server forcibly redirects apex to www, you have given Google a contradiction. It will resolve that contradiction without you, and while it does, your link equity sits split across two hosts. Backlinks people gave to webight.com and backlinks people gave to www.webight.com count toward different entries in the cluster until consolidation settles. You earned 100% of those links. You might be ranking on half of them.
Why the 307 made it worse
Redirect status codes carry meaning beyond "go over there."
A 301 or 308 says: this move is permanent, update your records, pass everything to the new URL.
A 307 says: this move is temporary, I might come back, keep checking the old address.
My server was answering with a 307. So even the redirect, the one signal that pointed at www, was whispering "but don't commit to this." Google handles temporary redirects by keeping the source URL as the candidate canonical longer and re-crawling it to see if the redirect went away. Slower consolidation, longer ambiguity, more crawl budget burned on a URL I never wanted indexed.
Where did the 307 come from? Next.js. NextResponse.redirect() in middleware defaults to 307. A redirect in next.config.ts with permanent: false also gives you 307. The browser follows it instantly, the page loads, everything looks fine, and the wrong status code ships to production. I never noticed because there was nothing visible to notice.
Check your own site in under a minute
You don't need a tool or an audit subscription for this. You need curl. Run these 4 lines against your own domain:
curl -sI https://yourdomain.com/
curl -sI https://www.yourdomain.com/
curl -sI http://yourdomain.com/
curl -sI http://www.yourdomain.com/
-s is silent, -I fetches headers only. Look at two things in each response: the status line and the location header. Exactly one of those four should return 200. The other three should answer with 301 or 308 pointing at the winner, in a single hop.
Here's what mine returned before the fix:
HTTP/2 307
location: https://www.webight.com/
Then check what your pages claim:
curl -s https://www.yourdomain.com/ | grep -o '<link rel="canonical" href="[^"]*"'
Mine printed href="https://webight.com". Server says www, page says apex. The entire bug, visible in 2 lines of terminal output. If your two outputs name the same host, you're clean and you can stop reading. If they don't, keep going.
The fix: pick one host, make the code match
Step one is a decision, and the decision matters less than making it. www or apex, either works. I picked www.webight.com because the server was already sending everyone there; flipping the redirect direction would have been a second migration for zero benefit. If you're starting fresh, www is mildly easier because CDNs prefer CNAME records on subdomains. That's it. Pick and never revisit.
Step two: hunt down every place your codebase writes the host, and make them agree. In my Next.js app that meant the root layout:
// src/app/layout.tsx
import type { Metadata } from "next";
export const metadata: Metadata = {
metadataBase: new URL("https://www.webight.com"),
alternates: {
canonical: "https://www.webight.com",
},
};
metadataBase is the quiet hero here. Every relative Open Graph URL and per-page canonical resolves against it, so fixing it fixes a whole category of mismatches at once.
Then the sitemap. Same audit found 12 deleted case-study URLs still sitting in mine, all pointing at the apex host. Both problems, one file:
// src/app/sitemap.ts
import type { MetadataRoute } from "next";
const BASE = "https://www.webight.com";
export default function sitemap(): MetadataRoute.Sitemap {
return [
{ url: BASE, lastModified: new Date(), priority: 1 },
{ url: `${BASE}/services`, lastModified: new Date() },
{ url: `${BASE}/work`, lastModified: new Date() },
{ url: `${BASE}/pricing`, lastModified: new Date() },
{ url: `${BASE}/contact`, lastModified: new Date() },
];
}
Step three: make the redirect permanent. On Vercel, go to Project, Settings, Domains, set the www domain as primary, and the apex redirect becomes a 308 automatically. If your redirect lives in code instead, one word changes the status:
// next.config.ts
async redirects() {
return [
{
source: "/:path*",
has: [{ type: "host", value: "webight.com" }],
destination: "https://www.webight.com/:path*",
permanent: true, // 308, signals pass to the target
},
];
}
Step four, verify. Same curl, new answer:
curl -sI https://webight.com/ | grep -iE "^HTTP|^location"
HTTP/2 308
location: https://www.webight.com/
And the canonical grep now prints www. Server and page finally telling the same story.
The deeper lesson is an engineering one, and it's older than SEO: single source of truth. My bug existed because the host was written by hand in 5 different places, and hand-written copies drift. The durable fix is one constant that everything imports:
// src/lib/site.ts
export const SITE_URL = "https://www.webight.com";
After this, drifting takes effort. Before this, drifting takes nothing.
For the record, the host fix was one item in a longer audit that also killed a 4,190ms hero render delay and removed 22.5 KiB of render-blocking CSS, and the scores landed at 96, 100, 100, 100. But the canonical mismatch is the one I'd tell you to check first, because it's the only one your tools will never flag, and the only one you can find in 60 seconds with software already installed on your machine.
So open a terminal right now and run those 4 curl lines against your own domain. If all four answers agree on one host, good, you spent a minute confirming you're fine. If they don't, you just found out Google has been splitting your site in half, and you know exactly how to fix it before lunch.
Found a 307 on your site? Tell me what it was, I read every reply.
We build custom platforms, websites, and automation.
The two people who build it are the two you talk to, and every price is on the page.

Garvit Sharma
Full-stack developer and co-founder of Webight, a two-person web and AI studio in India. He writes these from real client work. More about us.
Keep reading
// RELATEDA Client Paid 3 Agencies for SEO Before Me. None of Them Opened the Website Code.
webight.comA Client Paid 3 Agencies for SEO Before Me. None of Them Opened the Website Code.
7 MIN READ
One Cloudflare Worker Saved My Client's App When Supabase Got Blocked. It Also Cut TTFB in Half.
webight.comOne Cloudflare Worker Saved My Client's App When Supabase Got Blocked. It Also Cut TTFB in Half.
6 MIN READ
The Contact Form Setup That Stopped Landing in Spam. Resend, Next.js, DKIM.
webight.comThe Contact Form Setup That Stopped Landing in Spam. Resend, Next.js, DKIM.
6 MIN READ