high
Malformed sitemap entries
3 broken addresses
Indexability · Crawl efficiency · Backend
This sitemap entry contains an unresolved template placeholder.
${siteMapUrl.loc}
Fix Fix the sitemap generator so every <loc> is an absolute, fully resolved HTTPS URL. Entries containing an unresolved template placeholder or a literal "undefined" indicate a variable that was never substituted — trace it to the generating code rather than removing the URLs by hand.
3 broken addresses are not valid crawlable addresses, repeated across 6 sitemap entries. contains an unresolved template placeholder; contains whitespace; contains a literal 'undefined', 'null' or 'NaN', which means a template variable resolved to nothing.
View the user story for developers
As a search engine, I should receive only fully resolved absolute URLs in a sitemap, so that no crawl budget is spent on addresses that cannot exist.
Acceptance criteria
Scenario: Every entry is an absolute URL
Given the full sitemap is re-generated
When each <loc> is read
Then each is an absolute https:// URL with no whitespace
And none contains an unresolved template placeholder
Scenario: The generator fails loudly rather than writing a broken entry
Given a product whose URL cannot be resolved
When the sitemap is generated
Then that entry is omitted and the failure is logged
Verification
curl -s https://demo.ivanets.co/sitemap.xml | grep -oE '<loc>[^<]*</loc>' | grep -vE '<loc>https://[^ <]+</loc>'
# expected: no output
Expected response
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
3 entries currently fails this. Written as observable outcomes, so every criterion is verifiable with an HTTP request and none of it assumes a particular platform.
high
Dead URLs still in the sitemap
29 pages
Indexability · Crawl efficiency · Backend
The URL returns HTTP 404 but is still listed in the sitemap.
demo.ivanets.co/catalogue/cooking/built-in-ovens/ardvane-au…
Fix The status code is fine; the defect is that a removed URL is still being advertised in the sitemap. Remove it from the sitemap generator.
View the user story for developers
As a search engine, I should not be offered URLs that no longer exist, so that crawl budget is spent on live products.
Acceptance criteria
Scenario: A retired trade page is requested
Given the URL https://demo.ivanets.co/catalogue/cooking/built-in-ovens/ardvane-aurora-200-oven/p/KV-900000
When a crawler requests it
Then the response status is 410
And the URL appears in no XML sitemap
Scenario: A retired commercial page has a successor
Given a URL marked "review" in the redirect map
When an owner decision has been recorded
Then the URL either 301s to a named live URL
Or is restored and returns 200
Scenario: The sitemap is clean after remediation
Given the full sitemap is re-crawled
When every declared URL is requested
Then no URL returns 404
Verification
curl -s -o /dev/null -w "%{http_code}\n" https://demo.ivanets.co/catalogue/cooking/built-in-ovens/ardvane-aurora-200-oven/p/KV-900000
# expected: 410
Expected response
HTTP/1.1 410 Gone
Content-Type: text/html; charset=utf-8
Written as observable outcomes, so every criterion is verifiable with an HTTP request and none of it assumes a particular platform.
high
Navigation not in server HTML
277 of 467 pages
Images & links · Indexing · Platform
No internal link to this URL appears in the server HTML of any page scanned.
demo.ivanets.co/catalogue/cooking/built-in-ovens/belquist-r…
Fix Render the links inside category listings, pagination and related-product modules server-side, so they exist in the HTML before JavaScript runs. Google does execute JavaScript, but it does so on a second pass that is slower and not guaranteed, and every other crawler, link-equity calculation and internal-search index sees only what is in the initial response.
277 of the 467 crawled URLs that could carry an inbound link — pages answering 200 in a linkable segment — have none, while every page carries about 25 identical navigation links. That pattern means the listings are rendered client-side, not that the pages are orphaned.
View the user story for developers
As a crawler, I should find the links to products in the HTML the server returns, so that the catalogue is reachable by following links and not only by reading the sitemap.
Acceptance criteria
Scenario: A category listing links its products before JavaScript runs
Given the category page /catalogue/cooking/hobs/ardvane-aurora-200-hob/p/KV-600000
When the HTML is requested with JavaScript disabled
Then it contains an anchor to every product shown on that page
And each anchor has an href a crawler can follow, not an onclick handler
Scenario: Pagination is reachable without JavaScript
Given a category with more products than fit on one page
When the first page is requested
Then the HTML contains a link to page two
And following those links reaches every product in the category
Scenario: Every product has at least one inbound internal link
Given the 277 URLs listed in this finding
When the site is crawled without executing JavaScript
Then each of them is reached from some other page
Verification
# Fetch a listing and count the product links in the raw HTML.
curl -s https://assets-cdn.kelverton-demo.invalid/catalogue/cooking/hobs/ardvane-aurora-200-hob/p/KV-600000 \
| grep -o 'href="[^"]*/product/[^"]*"' | sort -u | wc -l
# expected: the number of products the page displays, not 0
Expected response
A number matching the products shown on the page.
Today this returns 0 on listings that build their grid in the browser.
Google does execute JavaScript, so this is not "the pages are invisible" — it is that discovery is slower, less certain, and carries no internal link signal. Written as observable outcomes, so every criterion is verifiable with an HTTP request and none of it assumes a particular platform.
high
Structured data missing required properties
139 pages
Structured data · Rich results · Backend
1 structured-data node is missing the properties Google requires, so the page cannot qualify for the matching rich result.
demo.ivanets.co/catalogue/cooking/built-in-ovens/belquist-r…
Fix Add the missing properties. Google will not show a rich result when a required property is absent, even though the JSON-LD itself is valid.
View the user story for developers
As a search engine, I should find every required property on a product, so that the page qualifies for the product rich result instead of being skipped.
Acceptance criteria
Scenario: A product carries the required properties
Given the URL https://demo.ivanets.co/catalogue/cooking/built-in-ovens/belquist-ransom-189x-oven/p/KV-100018
When its Product structured data is read
Then name, image and offers are present
And offers carries price, priceCurrency and availability
Scenario: A product with no price is not advertised as purchasable
Given a product with no price in the catalogue
When its page is generated
Then no offers block is emitted rather than one with an empty price
Verification
curl -s https://demo.ivanets.co/catalogue/cooking/built-in-ovens/belquist-ransom-189x-oven/p/KV-100018 | grep -o '"\(name\|image\|price\|priceCurrency\|availability\)":' | sort -u
# expected: all five present
Expected response
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
"offers":{"@type":"Offer","price":"…","priceCurrency":"UAH","availability":"…"}
139 pages are missing at least one. Written as observable outcomes, so every criterion is verifiable with an HTTP request and none of it assumes a particular platform.
high
Soft 404s
5 pages
Indexability · Indexing · Backend
The URL redirects to the homepage. Google may treat a redirect to an unrelated page as a soft 404: the old URL stays in the index, the redirect earns nothing, and crawl budget is spent re-checking it.
demo.ivanets.co/brands/c/B901
Fix Either 301 to a genuine replacement page, or return 404 or 410. A redirect to the homepage may be treated as a soft 404: it keeps the old URL in the index and earns nothing.
high
Internal links to removed pages
3 pages
Internal links · Crawl efficiency · Backend
Links to https://demo.ivanets.co/catalogue/cooking/built-in-ovens/ardvane-aurora-200-oven/p/KV-900000 (HTTP 404) with the anchor "Ardvane Aurora 200 oven".
demo.ivanets.co/help/spare-parts
Fix Update or remove the links listed. A removed page can be de-indexed correctly and still be linked from live pages, which wastes crawl budget, leaks internal link equity into nothing, and sends visitors to an error. This is usually a stale navigation block, a "related products" module reading from an unfiltered query, or a hard-coded footer link.
3 links from 3 pages point at 3 URLs.
high
Content not server-rendered
25 pages
Content · Indexing · Platform
The server HTML contains only 111 words of text.
demo.ivanets.co/help/delivery
high
No structured data
220 pages
Structured data · Rich results · Backend
No JSON-LD structured data was found in the server-rendered HTML.
demo.ivanets.co/catalogue/cooling/fridge-freezers/belquist-…
Fix Add schema.org JSON-LD describing the page: Product/Offer for product pages, Article for editorial, Organization + WebSite on the home page.
medium
Parameterised URLs published in the sitemap
90 sitemap entries
Indexability · Crawl efficiency · Backend
?lat= carries 90 distinct parameter combinations.
demo.ivanets.co/store/aberdeen?lat=57.1372&long=-2.1068
Fix
- Stop emitting parameterised URLs into the sitemap. A sitemap should list only the canonical URLs you want crawled.
- Give each parameterised URL a rel="canonical" pointing at the clean page, and leave crawling allowed so the canonical can actually be read.
- Only once the parameterised URLs have dropped out of the index, consider a robots.txt Disallow — and treat it purely as a crawl-budget decision, never as a de-indexing one. Blocking before step 2 has taken effect strands the duplicates in the index with no way to consolidate them.
90 of 494 sitemap URLs (18%) are parameterised or filtered variants: ?lat, ?long 90 of them are ?lat / ?long permutations of a single page rather than product facets, so the target is the unparameterised page — URL-parameter handling suits those better than a canonical on each one.
medium
Out-of-stock products — catalogue check needed
18 pages
Indexability · Indexing · Merchandising, Backend
The page returns HTTP 200 and is listed in the sitemap, while its Product structured data declares availability: OutOfStock. Out-of-stock is a valid indexable state for a product that will return, so this is not automatically a fault — but it cannot be told apart from a discontinued product without the catalogue.
demo.ivanets.co/catalogue/cooking/built-in-ovens/belquist-r…
Fix Split these against the catalogue. Products that will return are correct as they stand — keep them indexed with the current markup. Products that are discontinued should answer 404 or 410, or 301 to a comparable successor, and leave the sitemap.