Technical SEO is rarely about the words on the page - it is about addresses and about the server's responses. A product page in a camera store serves three at once: the shopper in a browser, the search crawler, and the code that walks the site link by link. The goal is single - every valuable entity should have one stable, indexable URL, and its duplicates should not compete for a place in the results.
The naive view is convincing: publish the pages, add links, and the engine will sort it out. It does sort things out fairly well, but the page for a single camera is almost always reachable at a dozen addresses - with a sort parameter, with a campaign tag, over http and https, with and without a trailing slash, inside a catalog filter and in a language variant. To a person this is one page. To a machine - different URLs with identical content.
This is where the model breaks. The crawler spends its limited crawl budget on clones instead of new products. Signals - inbound links, behavior, authority - get smeared across the copies, and none gathers enough weight. A random variant lands in the index: an address with a tracking tag, or a filtered catalog instead of the clean product URL. The user sees an ugly address in the results, and the store sees its rankings slip.
The remedy is simple in principle and demanding in discipline: the URL is the identity of the entity, the server response is the contract with the crawler. Several tools divide the duties, and confusing them is dangerous. robots.txt controls crawling - which paths the robot may request. The sitemap.xml file is a discovery hint: a list of canonical addresses worth finding and recrawling. The canonical tag says which of several similar pages to treat as the main one. The meta robots tag with the value noindex controls indexing - it allows crawling but forbids the display. HTTP status codes report what happened to an address.
The key to all of it is telling crawling and indexing apart - this is where intuition fails. It seems logical to close a utility or duplicate page in robots.txt so it stays out of search. But the block only prevents the page from being requested, not from appearing in the index: with external links the engine may show the address with no description, on the URL alone. Worse, because fetching the page is forbidden, the robot never sees the noindex on it - and there is nothing left to remove it from the index. The rule: to guarantee a page is not indexed, allow the crawl and forbid the display through noindex.
Status codes are the second half of the contract. A permanent move to a new address is a 301 or a 308: the old weight passes to the new URL. A temporary move is a 302 or a 307. A discontinued product answers with a 404 or a 410, honestly reporting that the page is gone and freeing up crawl budget. A duplicate a user still needs - a print version, say - stays available but points its canonical at the main version.
| Situation | HTTP / mechanism |
|---|---|
| Moved permanently | 301 or 308 |
| Moved temporarily | 302 or 307 |
| Gone for good | 404 or 410 |
| Duplicate a user still needs | canonical to the main version |
| Page must not be indexed | noindex, but do not block the crawl |
A separate question is how the page reaches the crawler. Critical content, links, the title, the canonical, and structured data are safer to deliver right in the source HTML from the server. Client-side rendering (CSR) is indexable too - the engine executes JavaScript - but it adds points of failure and delays the moment the page acquires meaning: the crawler must wait for the scripts, run them, and only then see the content. Every extra step is a chance that the canonical is not set and the card enters the index half-empty.
Is the complexity worth paying for? Yes, when there are many entities living in a catalog with filters, sort orders, and languages: duplicates appear on their own, and without canonicalization the results turn to mush. The classic failure: the card was closed in robots.txt as a duplicate, an external link dragged it into the index anyway, the robot never read the noindex - and a bare address with no description hangs in search while the real product page competes with itself. Address discipline is cheaper than untangling that after the fact.
# robots.txt - controls crawling, not indexing
User-agent: *
Disallow: /cart
Disallow: /*?sort=
Sitemap: https://example.com/sitemap.xml<link rel="canonical"
href="https://example.com/products/camera" />
<meta name="robots" content="index,follow" />