Sitemap

How to Check On-Page SEO on Localhost

8 min readAug 16, 2026

--

Every audit tool wants a public URL. Your page does not have one yet, and that is exactly when checking it is cheapest.

I have been building websites since 1999. One habit has outlived every technology I learned in that time, and it is the wrong habit: we ship the site first, then we find out what was wrong with it.

Type “localhost seo” into Google and look at what it offers you. “localhost seo check.” “localhost seo checker.” People are looking for this. What they find is a wall.

Press enter or click to view image in full size

Why Localhost Is a Blind Spot for SEO Tools

Almost every audit tool works the same way. You paste in a URL, their server visits it, downloads the page, and reports back. There is nothing wrong with that design, but it carries one hard requirement: your page has to be reachable from the public internet.

Now count how much of your work is not reachable. The site running on your machine at localhost:3000. The staging server you use before a client sees anything. An intranet sitting behind a company firewall. Pages behind a login: the account screen, the cart, the checkout step. The draft you have not published yet.

All of that is real work, and all of it will face Google one day. None of it can be inspected today by the tools everybody reaches for.

The timing is what stings. The cheapest possible moment to fix an SEO mistake is while nobody has seen the page. Finding it in Search Console a week after launch, fixing it, then waiting for Google to come back and recrawl is the most expensive route available. We take that route because the tools leave us no other one.

Press enter or click to view image in full size

So let me go through the ways out, including the ones I used for years before we built something better.

Four Ways to Check SEO on Localhost

1. Tunnel Localhost to a Public URL

You point a tunneling service at your dev server and it hands you a temporary public address. Now hosted tools can reach your page.

This works, and it lies to you in one specific way. The tunnel gives you somebody else’s hostname. Your canonical tag, your hreflang set, and your robots.txt rules are all judged against that hostname instead of yours, so every report about them is wrong. On top of that you have opened your development machine to the internet, and anything behind a login is still invisible, because the remote crawler has no session.

Press enter or click to view image in full size

Use it to look at page structure. Do not trust a single word it says about indexing.

2. Save the Page and Paste the HTML

Some checkers accept raw source instead of a URL. It sounds like the clean answer and it fails twice.

You are pasting source HTML, so everything JavaScript builds after load is missing. On a modern stack that can be most of the page. Worse, HTTP headers do not survive a copy and paste. X-Robots-Tag lives in a header, never in the HTML, so a page that is fully blocked from indexing will come back looking perfectly healthy.

3. Lighthouse in Chrome DevTools

Lighthouse runs locally, sees your rendered page, and costs nothing. For performance it is excellent and I use it constantly.

Its SEO category is another matter, and deliberately so. It checks a short list of basics and stops there. It will not put your source HTML next to your rendered page. It will not read your robots.txt rules crawler by crawler. It will not tell you that your canonical and your hreflang contradict each other. Lighthouse was never trying to be an on-page SEO audit, so treat a green SEO score as “no obvious blunders,” not as “checked.”

Press enter or click to view image in full size

4. Check It by Hand

curl for the headers, view-source for the raw HTML, DevTools for the rendered DOM, then read all three and compare them yourself.

This is the only option on the list that is fully accurate, and it is the reason on-page SEO gets skipped. You will do it once for the home page. You will not do it for forty templates on every deploy. Correct and unrepeatable is the same as not done.

Running the Check Inside the Browser Instead

Look at what all four workarounds have in common. Each one is trying to get the page to a tool. Meanwhile the one thing that can already see the page, perfectly, with your session and your JavaScript and your real headers, is sitting right there. It is your browser.

We had been running a thorough on-page analysis engine for our own clients for a long time, always pointed at public URLs from our servers. At some point the obvious thing landed: take that core out of the server and put it in the browser.

Press enter or click to view image in full size

That became On Page SEO Checker, a free Chrome extension. The whole analysis runs inside the tab you have open. Your page is uploaded nowhere and no request reaches our servers, which is the only honest way to build this: the page is one your browser can reach and ours cannot. There is no page limit and no daily quota, because there is no server cost to recover.

The summary tab, running against a page on localhost. The verdict at the top is one sentence, and the five signals behind it are listed underneath.

Get SEO’s stories in your inbox

Join Medium for free to get updates from this writer.

The rest of this article is the checklist itself. It is worth running whether you use the extension, another tool, or your own hands.

What to Check Before You Deploy

The Indexability Chain, Read in Google’s Order

Five signals decide whether a page can enter the index: meta robots, X-Robots-Tag, robots.txt, canonical, and hreflang. Checking them one at a time tells you very little. What matters is whether they agree, and which one wins when they do not.

Here is my favorite example, because it looks so responsible. You put a noindex tag on a page, and you also block its path in robots.txt. Two locks on one door. Except Google now never downloads that page, so it never reads your noindex, and the page can sit in the index indefinitely. Two correct decisions produce a wrong outcome purely by standing next to each other.

You will not catch that by eye. You catch it by reading the five signals as one chain.

Source HTML Against the Rendered Page

Put the server’s first response beside the DOM after JavaScript has finished, and compare the title, the canonical, the meta robots directive, the H1, and the hreflang set.

Two columns side by side. On this page the title and the H1 genuinely differ, while the canonical and meta robots agree.

On a modern framework this gap is where the surprises live. A title that reads correctly in the browser can be something else entirely in the response Google’s crawler received first.

Title and Description in Pixels, Not Characters

Google truncates search snippets by pixel width, not by character count. This is why character counters mislead you. “Illinois” and “lilliput” are both eight letters and they are nowhere near the same width on screen.

Measure the rendered width. A title that fits at 55 characters of narrow letters can be cut at 45 characters of wide ones.

The Heading Tree, Read as a Tree

Not “is there an H1.” The question is whether the hierarchy holds: no skipped levels, no second H1 that a component quietly injected, no H4 sitting under an H2 with no H3 in between.

Headings framed on the page itself with their level badges. You read the hierarchy off the page rather than out of a report.

Reading this on the page instead of in a list is faster, and it makes component-level mistakes obvious. Layout bugs and heading bugs usually turn out to be the same bug.

Missing alt Attributes, Kept Apart From alt=””

These two are not the same thing and tools that lump them together create busywork.

An empty alt is a decision. It says this image is decorative and screen readers should skip it. A missing alt attribute is an omission. Only the second one is a finding.

Which Crawlers Your robots.txt Actually Allows

Search is not only Google anymore. People ask answer engines, and those engines send their own crawlers: GPTBot, ClaudeBot, Google-Extended, PerplexityBot, CCBot, and others. Your robots.txt has an answer for each of them right now, whether you wrote one deliberately or inherited it.

The bot matrix. On this site GPTBot is allowed and the rest are blocked; every row carries its own explanation.

Check llms.txt while you are there. Blocking these crawlers can be exactly the right call. Blocking them without knowing it is not a call at all.

Core Web Vitals Measured in Your Own Tab

LCP, CLS, INP, FCP, TTFB, plus DOM milestones and transfer sizes.

A remote testing server reports what a page did on that server’s connection. That is an estimate about somebody else’s device. A measurement taken in the tab where the page actually loaded is a fact about the page in front of you. Neither replaces field data from real users, but only one of them is available before launch.

What This Approach Cannot Do

I do not trust a pitch that never names its limits, so here are ours.

It works on one page at a time, the tab you have open. Crawling a thousand-page site end to end is a different job and needs a different instrument.

It says nothing about rankings. It does not know your position, your competitors, or search volume for anything. Those require outside data sources and this extension connects to none. For the same reason it shows no backlinks.

It makes four requests, and all four go to the page’s own server: robots.txt, llms.txt, one HEAD, and one GET. They go to your site, never to ours.

The Short Version

Google’s own autocomplete will tell you people are searching for “localhost seo check.” Every tool they land on asks for a public URL, which is the one thing a localhost page does not have.

You have four ways around that. A tunnel that misreports your hostname, pasted HTML that loses your headers, a Lighthouse SEO score that was never meant to be an audit, or an hour of manual checking you will not repeat next week.

Or you can run the analysis where the page already is.

The extension is free on the Chrome Web Store: On Page SEO Checker. Install it, open your localhost:3000, and look at your page before anyone else does.

I write about SEO and web development at Türk SEM. The longer version of this story, about why we built the thing, is here.

--

--