Skip to content

A sample report

The same document a verified owner receives, produced by the shipped rules from a storefront we wrote ourselves.

Synthetic storefront

www.deep-synthetic.example is not a real shop. It is a storefront we authored for our own tests — every product, category, extension and defect in it was written by hand, and the hostname is under a reserved domain that resolves nowhere. We do not publish an audit of somebody else’s site as marketing, which is the same commitment the crawler page and the partner clauses make to merchants who are not our customers.

The findings, the scores and the skipped checks below are not written copy: they are what the rules in the product produce from that storefront, at a standard audit depth, rendered at the Enterprise plan so nothing is hidden behind a lock. The executive summary a language model writes is absent, because no model was called to produce this document and we do not fabricate one.

SuiteCommerce health report — www.deep-synthetic.example

Generated 2026-09-15T00:00:00.000Z

Scores

81 / 100Overall health

Host
www.deep-synthetic.example
Platform
sca
Release
2024.1.30 (certain, modern family)
Theme
none detected
Extensions
2
Audit depth
standard
Pages fetched
60
Pages rendered
20
Generated
2026-09-15T00:00:00.000Z
SEO58 / 100

coverage 72%

Exposure80 / 100

coverage 74%

Content90 / 100

coverage 84%

Performance98 / 100

coverage 86%

Accessibility94 / 100

coverage 100%

Platform95 / 100

coverage 86%

SEO58 / 100 · coverage 72%

SEO findings
SeverityConfidenceStatusFindingAffectedSourceEvidence
ErrorCertainUnknownPlatform: Pages served without prerendering60 page(s) were served without prerendering: no version header and no generator body class, so what a search engine receives is the empty shell.60 pages of 60100%rule

Platform: Pages served without prerendering

60 page(s) were served without prerendering: no version header and no generator body class, so what a search engine receives is the empty shell.

Affected
60 pages of 60
Attributed to
NetSuite platform
Rule
prerender/not-applied
Source
rule

Evidence (25)

  • / → fetch.headers1 fieldpage:p000#fetch.headers
  • / → body.seoSupportClassfalsepage:p000#body.seoSupportClass
  • /Department-1 → fetch.headers1 fieldpage:p001#fetch.headers
  • /Department-1 → body.seoSupportClassfalsepage:p001#body.seoSupportClass
  • /department-1 → fetch.headers1 fieldpage:p002#fetch.headers
  • /department-1 → body.seoSupportClassfalsepage:p002#body.seoSupportClass
  • /department-1/custitem_colour/Grey → fetch.headers1 fieldpage:p003#fetch.headers
  • /department-1/custitem_colour/Grey → body.seoSupportClassfalsepage:p003#body.seoSupportClass
  • /department-1/custitem_colour/Grey/custitem_material/Paper/custitem_size/Small → fetch.headers1 fieldpage:p004#fetch.headers
  • /department-1/custitem_colour/Grey/custitem_material/Paper/custitem_size/Small → body.seoSupportClassfalsepage:p004#body.seoSupportClass
  • /department-1/custitem_material/Paper → fetch.headers1 fieldpage:p005#fetch.headers
  • /department-1/custitem_material/Paper → body.seoSupportClassfalsepage:p005#body.seoSupportClass
  • /department-1/custitem_size/Small → fetch.headers1 fieldpage:p006#fetch.headers
  • /department-1/custitem_size/Small → body.seoSupportClassfalsepage:p006#body.seoSupportClass
  • /department-1/section-1 → fetch.headers1 fieldpage:p007#fetch.headers
  • /department-1/section-1 → body.seoSupportClassfalsepage:p007#body.seoSupportClass
  • /department-1/section-1/aisle-1 → fetch.headers1 fieldpage:p008#fetch.headers
  • /department-1/section-1/aisle-1 → body.seoSupportClassfalsepage:p008#body.seoSupportClass
  • /department-1/section-1/aisle-2 → fetch.headers1 fieldpage:p009#fetch.headers
  • /department-1/section-1/aisle-2 → body.seoSupportClassfalsepage:p009#body.seoSupportClass
  • /department-1/section-1/aisle-3 → fetch.headers1 fieldpage:p010#fetch.headers
  • /department-1/section-1/aisle-3 → body.seoSupportClassfalsepage:p010#body.seoSupportClass
  • /department-1/section-2 → fetch.headers1 fieldpage:p011#fetch.headers
  • /department-1/section-2 → body.seoSupportClassfalsepage:p011#body.seoSupportClass
  • /department-1/section-2/aisle-1 → fetch.headers1 fieldpage:p012#fetch.headers

Fix

NetSuite support, naming the URLs and the absence of x-prerender-version; and Setup > SuiteCommerce Advanced > Set Up Web Site for the domain configurationa configuration change

  1. Request the affected URLs with a browser user agent and confirm the response carries no x-prerender-version header.
  2. Check that the domain is the one configured on the Web Site record: prerendering follows the configured shopping domain, not an alias.
  3. Raise a support case with the URLs and the response headers, because the renderer is platform-side and not configurable from the account.
  • evidence capped at 25 of 120 pointers
WarningCertainUnknownPublished landing pages missing from the sitemap82 of 82 published landing pages are not in the sitemap (for example /about-the-fixture, /guide-1, /guide-2), so they are found only if something links to them.site-widerule

Published landing pages missing from the sitemap

82 of 82 published landing pages are not in the sitemap (for example /about-the-fixture, /guide-1, /guide-2), so they are found only if something links to them.

Affected
site-wide
Attributed to
cause not attributed
Rule
discovery/sitemap-landing-gap
Source
rule

Evidence (25)

  • Discovery › sitemap › byType2 fieldsdiscovery:sitemap#byType
  • CMS page cms-about8 fieldscms:cms-about
  • CMS page cms-guide-18 fieldscms:cms-guide-1
  • CMS page cms-guide-28 fieldscms:cms-guide-2
  • CMS page cms-guide-38 fieldscms:cms-guide-3
  • CMS page cms-guide-48 fieldscms:cms-guide-4
  • CMS page cms-guide-58 fieldscms:cms-guide-5
  • CMS page cms-guide-68 fieldscms:cms-guide-6
  • CMS page cms-guide-78 fieldscms:cms-guide-7
  • CMS page cms-guide-88 fieldscms:cms-guide-8
  • CMS page cms-guide-98 fieldscms:cms-guide-9
  • CMS page cms-guide-108 fieldscms:cms-guide-10
  • CMS page cms-guide-118 fieldscms:cms-guide-11
  • CMS page cms-guide-128 fieldscms:cms-guide-12
  • CMS page cms-guide-138 fieldscms:cms-guide-13
  • CMS page cms-guide-148 fieldscms:cms-guide-14
  • CMS page cms-guide-158 fieldscms:cms-guide-15
  • CMS page cms-guide-168 fieldscms:cms-guide-16
  • CMS page cms-guide-178 fieldscms:cms-guide-17
  • CMS page cms-guide-188 fieldscms:cms-guide-18
  • CMS page cms-guide-198 fieldscms:cms-guide-19
  • CMS page cms-guide-208 fieldscms:cms-guide-20
  • CMS page cms-guide-218 fieldscms:cms-guide-21
  • CMS page cms-guide-228 fieldscms:cms-guide-22
  • CMS page cms-guide-238 fieldscms:cms-guide-23

Fix

Commerce Categories and Site Management Tools > Pages, the affected page records; and the Web Site record’s sitemap generationa configuration change

  1. Confirm each affected page is published rather than a draft, and that its type gives it a route of its own.
  2. Check that the page is attached to this Web Site record: the sitemap is generated per site.
  3. Regenerate the sitemap and re-crawl to confirm the pages appear.
WarningCertainUnknownA multi-language storefront declares no hreflang alternatesThis storefront publishes 3 languages and 58 indexable page(s) declare no hreflang alternates, so each translation competes with the others in search instead of being grouped with them.58 pages of 58100%rule

A multi-language storefront declares no hreflang alternates

This storefront publishes 3 languages and 58 indexable page(s) declare no hreflang alternates, so each translation competes with the others in search instead of being grouped with them.

Affected
58 pages of 58
Attributed to
SuiteCommerce core
Rule
seo/hreflang-missing-multilang
Source
rule

Evidence (25)

  • / → head.hreflang0 entriespage:p000#head.hreflang
  • /department-1 → head.hreflang0 entriespage:p002#head.hreflang
  • /department-1/custitem_colour/Grey → head.hreflang0 entriespage:p003#head.hreflang
  • /department-1/custitem_colour/Grey/custitem_material/Paper/custitem_size/Small → head.hreflang0 entriespage:p004#head.hreflang
  • /department-1/custitem_material/Paper → head.hreflang0 entriespage:p005#head.hreflang
  • /department-1/custitem_size/Small → head.hreflang0 entriespage:p006#head.hreflang
  • /department-1/section-1 → head.hreflang0 entriespage:p007#head.hreflang
  • /department-1/section-1/aisle-1 → head.hreflang0 entriespage:p008#head.hreflang
  • /department-1/section-1/aisle-2 → head.hreflang0 entriespage:p009#head.hreflang
  • /department-1/section-1/aisle-3 → head.hreflang0 entriespage:p010#head.hreflang
  • /department-1/section-2 → head.hreflang0 entriespage:p011#head.hreflang
  • /department-1/section-2/aisle-1 → head.hreflang0 entriespage:p012#head.hreflang
  • /department-1/section-2/aisle-2 → head.hreflang0 entriespage:p013#head.hreflang
  • /department-1/section-2/aisle-3 → head.hreflang0 entriespage:p014#head.hreflang
  • /department-1/section-3 → head.hreflang0 entriespage:p015#head.hreflang
  • /department-1/section-3/aisle-1 → head.hreflang0 entriespage:p016#head.hreflang
  • /department-1/section-3/aisle-2 → head.hreflang0 entriespage:p017#head.hreflang
  • /department-1/section-3/aisle-3 → head.hreflang0 entriespage:p018#head.hreflang
  • /department-2 → head.hreflang0 entriespage:p019#head.hreflang
  • /department-2/section-1 → head.hreflang0 entriespage:p020#head.hreflang
  • /department-2/section-1/aisle-1 → head.hreflang0 entriespage:p021#head.hreflang
  • /department-2/section-1/aisle-2 → head.hreflang0 entriespage:p022#head.hreflang
  • /department-2/section-1/aisle-3 → head.hreflang0 entriespage:p023#head.hreflang
  • /department-2/section-2 → head.hreflang0 entriespage:p024#head.hreflang
  • /department-2/section-2/aisle-1 → head.hreflang0 entriespage:p025#head.hreflang

Fix

An extension that adds alternate-language links to the head; core supplies no mechanism, so there is no configuration field to seta code change

  1. List the host serving each configured language from availableHosts.
  2. Add an extension that emits a rel="alternate" hreflang link per host on every indexable page, including a self-referencing entry.
  3. Add an x-default entry pointing at the host a visitor with no matching language should receive.
  4. Re-crawl each host and confirm the alternates agree with one another.
  • evidence capped at 25 of 58 pointers
WarningCertainUnknownCommerce categories missing from the sitemap52 of 52 commerce category pages are not in the sitemap (for example /department-1, /department-1/section-1, /department-1/section-1/aisle-1), so search engines find them only if something links to them.52 categories of 52100%rule

Commerce categories missing from the sitemap

52 of 52 commerce category pages are not in the sitemap (for example /department-1, /department-1/section-1, /department-1/section-1/aisle-1), so search engines find them only if something links to them.

Affected
52 categories of 52
Attributed to
cause not attributed
Rule
discovery/sitemap-category-gap
Source
rule

Evidence (25)

  • Discovery › sitemap › byType2 fieldsdiscovery:sitemap#byType
  • Category 1005 fieldscategory:100
  • Category 1106 fieldscategory:110
  • Category 1116 fieldscategory:111
  • Category 1126 fieldscategory:112
  • Category 1136 fieldscategory:113
  • Category 1206 fieldscategory:120
  • Category 1216 fieldscategory:121
  • Category 1226 fieldscategory:122
  • Category 1236 fieldscategory:123
  • Category 1306 fieldscategory:130
  • Category 1316 fieldscategory:131
  • Category 1326 fieldscategory:132
  • Category 1336 fieldscategory:133
  • Category 2005 fieldscategory:200
  • Category 2106 fieldscategory:210
  • Category 2116 fieldscategory:211
  • Category 2126 fieldscategory:212
  • Category 2136 fieldscategory:213
  • Category 2206 fieldscategory:220
  • Category 2216 fieldscategory:221
  • Category 2226 fieldscategory:222
  • Category 2236 fieldscategory:223
  • Category 2306 fieldscategory:230
  • Category 2316 fieldscategory:231

Fix

The commerce category records (Display in Site, and the primary URL flag), and the Web Site record’s sitemap generationa configuration change

  1. Check Display in Site on the affected category records: the sitemap generator skips categories that are not displayed.
  2. Confirm each category has a primary URL: a non-primary URL is an alias and is not listed.
  3. Regenerate the sitemap and re-crawl to confirm the categories appear.
WarningCertainUnknownThe two render passes emit different placeholders20 rendered page(s) emit different placeholders in the two passes: 1 present only in the browser (data-view:Synthetic.Promo#0). On this release the browser rebuilds the content area, so the cost is a flash rather than a wrong page — until the site is upgraded.20 pages of 20100%rule

The two render passes emit different placeholders

20 rendered page(s) emit different placeholders in the two passes: 1 present only in the browser (data-view:Synthetic.Promo#0). On this release the browser rebuilds the content area, so the cost is a flash rather than a wrong page — until the site is upgraded.

Affected
20 pages of 20
Attributed to
cause not attributed
Rule
prerender/placeholder-parity
Source
rule

Evidence (20)

  • / → body.placeholders.hash"4d14087380bf915899f6d5d49d312898539b61fd6a9890dc464274beb9a74c38"page:p000#body.placeholders.hash
  • /Department-1 → body.placeholders.hash"0bb677128af3a2f3a593548daf421958afa5a41f58d3c5e1f36e4a74df48a2f0"page:p001#body.placeholders.hash
  • /department-1 → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p002#body.placeholders.hash
  • /department-1/custitem_colour/Grey → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p003#body.placeholders.hash
  • /department-1/custitem_colour/Grey/custitem_material/Paper/custitem_size/Small → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p004#body.placeholders.hash
  • /department-1/custitem_material/Paper → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p005#body.placeholders.hash
  • /department-1/custitem_size/Small → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p006#body.placeholders.hash
  • /department-2 → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p019#body.placeholders.hash
  • /department-3 → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p031#body.placeholders.hash
  • /department-4 → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p035#body.placeholders.hash
  • /guide-41 → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p039#body.placeholders.hash
  • /guide-65 → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p040#body.placeholders.hash
  • /guide-66 → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p041#body.placeholders.hash
  • /guide-69 → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p042#body.placeholders.hash
  • /product-1 → body.placeholders.hash"027cdde8372314c61189a9381e497c2eafa5586632574588019b3c10e4942fd3"page:p043#body.placeholders.hash
  • /product-10 → body.placeholders.hash"027cdde8372314c61189a9381e497c2eafa5586632574588019b3c10e4942fd3"page:p044#body.placeholders.hash
  • /product-100 → body.placeholders.hash"027cdde8372314c61189a9381e497c2eafa5586632574588019b3c10e4942fd3"page:p045#body.placeholders.hash
  • /product-101 → body.placeholders.hash"027cdde8372314c61189a9381e497c2eafa5586632574588019b3c10e4942fd3"page:p046#body.placeholders.hash
  • /search?keywords=Grey → body.placeholders.hash"55cfead92b605aa0fb8b72a0410b532a66e732e860a22fe401c9020ef90257cc"page:p058#body.placeholders.hash
  • /this-page-does-not-exist-8c3dcdd1 → body.placeholders.hash"0bb677128af3a2f3a593548daf421958afa5a41f58d3c5e1f36e4a74df48a2f0"page:p059#body.placeholders.hash

Fix

The templates that wrap a [data-view] or [data-cms-area] element in a condition, and any view that adds or removes placeholders after rendera code change

  1. Find the placeholders the comparison names and the condition that decides whether they are emitted.
  2. Remove isPageGenerator from around the placeholder element itself (CORR-027): it may gate the content inside, never the container.
  3. Emit the same number of element children in both passes, even when the children are empty server-side.
  4. Re-crawl and confirm the placeholder hashes match.
WarningCertainUnknownPages sharing one <title>5 indexable page(s) share a <title> with another page across 1 duplicated title(s), so they compete with each other in search results.5 pages of 589%rule

Pages sharing one <title>

5 indexable page(s) share a <title> with another page across 1 duplicated title(s), so they compete with each other in search results.

Affected
5 pages of 58
Attributed to
cause not attributed
Rule
seo/title-duplicate
Source
rule

Evidence (5)

  • /department-1/custitem_colour/Grey → head.title"{{title}} | Deep Synthetic Store"page:p003#head.title
  • /department-1/custitem_colour/Grey/custitem_material/Paper/custitem_size/Small → head.title"{{title}} | Deep Synthetic Store"page:p004#head.title
  • /department-1/custitem_material/Paper → head.title"{{title}} | Deep Synthetic Store"page:p005#head.title
  • /department-1/custitem_size/Small → head.title"{{title}} | Deep Synthetic Store"page:p006#head.title
  • /search?keywords=Grey → head.title"{{title}} | Deep Synthetic Store"page:p058#head.title

Fix

Commerce Category › Page Title for a category; the facet `titleToken` and `titleSeparator` in the Facets configuration for a facet page; Item record › Web Store › Page Title for a producta content change

  1. Group the pages named in the evidence by the title they share.
  2. For a facet page inheriting its parent category title, set `titleToken` on the facet so the rendered title names the selected value.
  3. For two records sharing a Page Title, rewrite one so each title describes only its own page.
  4. Re-crawl and confirm each page returns a distinct <title>.
WarningCertainUnknownCanonical URLs point at a different host5 page(s) declare a canonical URL on a different host (www.deep-synthetic.example{{path}}), which asks search engines to index that host instead of this one.5 pages of 589%rule

Canonical URLs point at a different host

5 page(s) declare a canonical URL on a different host (www.deep-synthetic.example{{path}}), which asks search engines to index that host instead of this one.

Affected
5 pages of 58
Attributed to
cause not attributed
Rule
seo/canonical-cross-host
Source
rule

Evidence (5)

  • /department-1/custitem_colour/Grey → head.canonical"https://www.deep-synthetic.example{{path}}"page:p003#head.canonical
  • /department-1/custitem_colour/Grey/custitem_material/Paper/custitem_size/Small → head.canonical"https://www.deep-synthetic.example{{path}}"page:p004#head.canonical
  • /department-1/custitem_material/Paper → head.canonical"https://www.deep-synthetic.example{{path}}"page:p005#head.canonical
  • /department-1/custitem_size/Small → head.canonical"https://www.deep-synthetic.example{{path}}"page:p006#head.canonical
  • /search?keywords=Grey → head.canonical"https://www.deep-synthetic.example{{path}}"page:p058#head.canonical

Fix

Setup > SuiteCommerce Advanced > Set Up Web Site › the Website record domain, then any extension or theme template that writes an absolute canonicala configuration change

  1. Decide which host is the canonical one for this storefront.
  2. Correct the Website record domain, or the extension that hard-codes a host, so the canonical is built from the serving hostname.
  3. Redirect the other host to the canonical one so the two stop competing.
  4. Re-crawl and confirm each canonical names the serving host.
WarningLikelyUnknownPages with less visible text than their type needs58 indexable page(s) carry less visible text than their page type needs, the thinnest at 18 words.58 pages of 58100%rule

Pages with less visible text than their type needs

58 indexable page(s) carry less visible text than their page type needs, the thinnest at 18 words.

Affected
58 pages of 58
Attributed to
cause not attributed
Rule
seo/thin-content
Source
rule

Evidence (25)

  • / → body.visibleWordCount48page:p000#body.visibleWordCount
  • /department-1 → body.visibleWordCount22page:p002#body.visibleWordCount
  • /department-1/custitem_colour/Grey → body.visibleWordCount21page:p003#body.visibleWordCount
  • /department-1/custitem_colour/Grey/custitem_material/Paper/custitem_size/Small → body.visibleWordCount21page:p004#body.visibleWordCount
  • /department-1/custitem_material/Paper → body.visibleWordCount21page:p005#body.visibleWordCount
  • /department-1/custitem_size/Small → body.visibleWordCount21page:p006#body.visibleWordCount
  • /department-1/section-1 → body.visibleWordCount22page:p007#body.visibleWordCount
  • /department-1/section-1/aisle-1 → body.visibleWordCount22page:p008#body.visibleWordCount
  • /department-1/section-1/aisle-2 → body.visibleWordCount22page:p009#body.visibleWordCount
  • /department-1/section-1/aisle-3 → body.visibleWordCount22page:p010#body.visibleWordCount
  • /department-1/section-2 → body.visibleWordCount22page:p011#body.visibleWordCount
  • /department-1/section-2/aisle-1 → body.visibleWordCount22page:p012#body.visibleWordCount
  • /department-1/section-2/aisle-2 → body.visibleWordCount22page:p013#body.visibleWordCount
  • /department-1/section-2/aisle-3 → body.visibleWordCount22page:p014#body.visibleWordCount
  • /department-1/section-3 → body.visibleWordCount22page:p015#body.visibleWordCount
  • /department-1/section-3/aisle-1 → body.visibleWordCount22page:p016#body.visibleWordCount
  • /department-1/section-3/aisle-2 → body.visibleWordCount22page:p017#body.visibleWordCount
  • /department-1/section-3/aisle-3 → body.visibleWordCount22page:p018#body.visibleWordCount
  • /department-2 → body.visibleWordCount22page:p019#body.visibleWordCount
  • /department-2/section-1 → body.visibleWordCount22page:p020#body.visibleWordCount
  • /department-2/section-1/aisle-1 → body.visibleWordCount22page:p021#body.visibleWordCount
  • /department-2/section-1/aisle-2 → body.visibleWordCount22page:p022#body.visibleWordCount
  • /department-2/section-1/aisle-3 → body.visibleWordCount22page:p023#body.visibleWordCount
  • /department-2/section-2 → body.visibleWordCount22page:p024#body.visibleWordCount
  • /department-2/section-2/aisle-1 → body.visibleWordCount22page:p025#body.visibleWordCount

Fix

Commerce Category › Description for a category page; Item record › Web Store › Detailed Description for a product; the SMT page content for a landing pagea content change

  1. Fill the description field on the record behind each page named in the evidence.
  2. Confirm the text appears in the prerendered document and not only after the client pass, which is what a search engine reads.
  3. Re-crawl and confirm the visible word count rises above the threshold for the type.
  • evidence capped at 25 of 58 pointers
WarningCertainUnknownProduct structured data with fields absent or malformed15 Product/Offer node(s) across 15 page(s) are incomplete: image absent. A rich result needs every one of them.15 pages of 15100%rule

Product structured data with fields absent or malformed

15 Product/Offer node(s) across 15 page(s) are incomplete: image absent. A rich result needs every one of them.

Affected
15 pages of 15
Attributed to
SuiteCommerce core
Rule
structured/product-incomplete
Source
rule

Evidence (15)

  • /product-1 → head.jsonLd[0].validation[0]4 fieldspage:p043#head.jsonLd[0].validation[0]
  • /product-10 → head.jsonLd[0].validation[0]4 fieldspage:p044#head.jsonLd[0].validation[0]
  • /product-100 → head.jsonLd[0].validation[0]4 fieldspage:p045#head.jsonLd[0].validation[0]
  • /product-101 → head.jsonLd[0].validation[0]4 fieldspage:p046#head.jsonLd[0].validation[0]
  • /product-102 → head.jsonLd[0].validation[0]4 fieldspage:p047#head.jsonLd[0].validation[0]
  • /product-103 → head.jsonLd[0].validation[0]4 fieldspage:p048#head.jsonLd[0].validation[0]
  • /product-104 → head.jsonLd[0].validation[0]4 fieldspage:p049#head.jsonLd[0].validation[0]
  • /product-105 → head.jsonLd[0].validation[0]4 fieldspage:p050#head.jsonLd[0].validation[0]
  • /product-106 → head.jsonLd[0].validation[0]4 fieldspage:p051#head.jsonLd[0].validation[0]
  • /product-107 → head.jsonLd[0].validation[0]4 fieldspage:p052#head.jsonLd[0].validation[0]
  • /product-108 → head.jsonLd[0].validation[0]4 fieldspage:p053#head.jsonLd[0].validation[0]
  • /product-109 → head.jsonLd[0].validation[0]4 fieldspage:p054#head.jsonLd[0].validation[0]
  • /product-11 → head.jsonLd[0].validation[0]4 fieldspage:p055#head.jsonLd[0].validation[0]
  • /product-110 → head.jsonLd[0].validation[0]4 fieldspage:p056#head.jsonLd[0].validation[0]
  • /product-111 → head.jsonLd[0].validation[0]4 fieldspage:p057#head.jsonLd[0].validation[0]

Fix

The item record fields the JSON-LD reads (Store tab: Page Title, Store Display Image, pricing and stock), and the PDP view that builds the Offer nodea content change

  1. Fill the absent fields on the affected item records.
  2. Where availability is the absent field, check whether the PDP hides prices for anonymous shoppers: ProfileModel.hidePrices() omits price and availability from the Offer node, and the markup must then not claim to be an Offer.
  3. Re-crawl and confirm each Offer node carries price, priceCurrency and availability.
WarningCertainUnknownPages that never finished booting in the browser2 page(s) never finished booting in the browser: 0 had mounted at least one extension module, and the renderer collected 0 uncaught error(s) and 2 console error(s) on them. Every client-side measurement for those pages is reported as unavailable rather than as a bad score.2 pages of 307%rule

Pages that never finished booting in the browser

2 page(s) never finished booting in the browser: 0 had mounted at least one extension module, and the renderer collected 0 uncaught error(s) and 2 console error(s) on them. Every client-side measurement for those pages is reported as unavailable rather than as a bad score.

Affected
2 pages of 30
Attributed to
cause not attributed
Rule
prerender/readiness-timeout
Source
rule

Evidence (2)

  • /Department-1 → body.placeholders.hash"0bb677128af3a2f3a593548daf421958afa5a41f58d3c5e1f36e4a74df48a2f0"page:p001#body.placeholders.hash
  • /this-page-does-not-exist-8c3dcdd1 → body.placeholders.hash"0bb677128af3a2f3a593548daf421958afa5a41f58d3c5e1f36e4a74df48a2f0"page:p059#body.placeholders.hash

Fix

The extension entry points that mount on the affected pages, and their define dependency arraysa code change

  1. Open an affected page with the console visible and read the first uncaught error: an unresolved module id throws before mountToApp and stops every extension after it (07 § 9).
  2. Check for a readiness signal built on setTimeout(fn, 0) (CORR-033), which resolves before the thing it was waiting for.
  3. Confirm every extension service the page calls on load returns, rather than hanging.
  4. Re-crawl and confirm the page reaches a ready state.
WarningCertainUnknownPages sharing one meta description5 indexable page(s) share a meta description with another page across 1 duplicated description(s), so their search snippets are identical.5 pages of 589%rule

Pages sharing one meta description

5 indexable page(s) share a meta description with another page across 1 duplicated description(s), so their search snippets are identical.

Affected
5 pages of 58
Attributed to
cause not attributed
Rule
seo/meta-description-duplicate
Source
rule

Evidence (5)

  • /department-1/custitem_colour/Grey → head.metaDescription"{{title}}: a hand-written category page for the deep-depth tests."page:p003#head.metaDescription
  • /department-1/custitem_colour/Grey/custitem_material/Paper/custitem_size/Small → head.metaDescription"{{title}}: a hand-written category page for the deep-depth tests."page:p004#head.metaDescription
  • /department-1/custitem_material/Paper → head.metaDescription"{{title}}: a hand-written category page for the deep-depth tests."page:p005#head.metaDescription
  • /department-1/custitem_size/Small → head.metaDescription"{{title}}: a hand-written category page for the deep-depth tests."page:p006#head.metaDescription
  • /search?keywords=Grey → head.metaDescription"{{title}}: a hand-written category page for the deep-depth tests."page:p058#head.metaDescription

Fix

Commerce Category › Meta Description for a category; Item record › Web Store › Meta Tag HTML for a product; the SMT page settings for a landing pagea content change

  1. Group the pages named in the evidence by the description they share.
  2. Rewrite each so it describes only the products or content on that page.
  3. Where a facet page inherits the parent category description, decide whether the facet should be canonicalised to the category instead.
  4. Re-crawl and confirm each description is distinct.
InfoCertainUnknownFacet pages beyond the SEO limits still return 2001 facet combination(s) beyond the configured SEO limits still return 200 when requested. The limits suppress the links in the generated HTML and nothing more: they do not make these pages unavailable or tell a search engine to ignore them.site-widerule

Facet pages beyond the SEO limits still return 200

1 facet combination(s) beyond the configured SEO limits still return 200 when requested. The limits suppress the links in the generated HTML and nothing more: they do not make these pages unavailable or tell a search engine to ignore them.

Affected
site-wide
Attributed to
SuiteCommerce core
Rule
discovery/facet-over-limit-reachable
Source
rule

Evidence (2)

  • Discovery › facetUrls4 entriesdiscovery:facetUrls
  • Environment › seoRelevant › facetsSeoLimits3 fieldsenv:seoRelevant.facetsSeoLimits

Fix

Setup > SuiteCommerce Advanced > Configuration, the Facets SEO limits group; and the robots.txt field on the Web Site recorda configuration change

  1. Decide whether these combinations should be excluded or merely unlinked. The configuration only unlinks them.
  2. To exclude them, disallow the facet path or parameter pattern in robots.txt.
  3. Confirm the over-limit pages carry a canonical pointing at the page that should rank instead.
InfoHeuristicUnknownThe <h1> and the <title> are the same string1 page(s) use one string for both the <h1> and the <title>, so the title adds nothing a shopper cannot already see on the page.1 page of 58 (home)2%rule

The <h1> and the <title> are the same string

1 page(s) use one string for both the <h1> and the <title>, so the title adds nothing a shopper cannot already see on the page.

Affected
1 page of 58 (home)
Attributed to
cause not attributed
Rule
seo/h1-equals-title
Source
rule

Evidence (2)

  • / → head.title"Deep Synthetic Store"page:p000#head.title
  • / → body.headings[0]3 fieldspage:p000#body.headings[0]

Fix

Item record › Web Store › Page Title for a product; Commerce Category › Page Title for a category; the SMT page settings for a landing pagea content change

  1. Decide what the title should add that the heading does not: the brand, the parent category, the model number, or the offer.
  2. Rewrite Page Title on the record that supplies it, leaving the page heading alone.
  3. Keep the result inside the length seo/title-length checks.
InfoCertainUnknownProduct and listing pages publish no BreadcrumbList38 category and facet and search page(s) publish no BreadcrumbList, so search results for them show the raw URL path instead of a readable trail.38 pages of 38100%rule

Product and listing pages publish no BreadcrumbList

38 category and facet and search page(s) publish no BreadcrumbList, so search results for them show the raw URL path instead of a readable trail.

Affected
38 pages of 38
Attributed to
SuiteCommerce core
Rule
structured/breadcrumb-missing
Source
rule

Evidence (25)

  • /department-1 → head.jsonLd0 entriespage:p002#head.jsonLd
  • /department-1/custitem_colour/Grey → head.jsonLd0 entriespage:p003#head.jsonLd
  • /department-1/custitem_colour/Grey/custitem_material/Paper/custitem_size/Small → head.jsonLd0 entriespage:p004#head.jsonLd
  • /department-1/custitem_material/Paper → head.jsonLd0 entriespage:p005#head.jsonLd
  • /department-1/custitem_size/Small → head.jsonLd0 entriespage:p006#head.jsonLd
  • /department-1/section-1 → head.jsonLd0 entriespage:p007#head.jsonLd
  • /department-1/section-1/aisle-1 → head.jsonLd0 entriespage:p008#head.jsonLd
  • /department-1/section-1/aisle-2 → head.jsonLd0 entriespage:p009#head.jsonLd
  • /department-1/section-1/aisle-3 → head.jsonLd0 entriespage:p010#head.jsonLd
  • /department-1/section-2 → head.jsonLd0 entriespage:p011#head.jsonLd
  • /department-1/section-2/aisle-1 → head.jsonLd0 entriespage:p012#head.jsonLd
  • /department-1/section-2/aisle-2 → head.jsonLd0 entriespage:p013#head.jsonLd
  • /department-1/section-2/aisle-3 → head.jsonLd0 entriespage:p014#head.jsonLd
  • /department-1/section-3 → head.jsonLd0 entriespage:p015#head.jsonLd
  • /department-1/section-3/aisle-1 → head.jsonLd0 entriespage:p016#head.jsonLd
  • /department-1/section-3/aisle-2 → head.jsonLd0 entriespage:p017#head.jsonLd
  • /department-1/section-3/aisle-3 → head.jsonLd0 entriespage:p018#head.jsonLd
  • /department-2 → head.jsonLd0 entriespage:p019#head.jsonLd
  • /department-2/section-1 → head.jsonLd0 entriespage:p020#head.jsonLd
  • /department-2/section-1/aisle-1 → head.jsonLd0 entriespage:p021#head.jsonLd
  • /department-2/section-1/aisle-2 → head.jsonLd0 entriespage:p022#head.jsonLd
  • /department-2/section-1/aisle-3 → head.jsonLd0 entriespage:p023#head.jsonLd
  • /department-2/section-2 → head.jsonLd0 entriespage:p024#head.jsonLd
  • /department-2/section-2/aisle-1 → head.jsonLd0 entriespage:p025#head.jsonLd
  • /department-2/section-2/aisle-2 → head.jsonLd0 entriespage:p026#head.jsonLd

Fix

The theme template that renders the breadcrumb trail, and its viewa code change

  1. Render the breadcrumb through the core breadcrumb view rather than a bespoke template, so its getViewJsonLd() contribution reaches the head.
  2. Where the trail is bespoke, add a BreadcrumbList node whose items match the rendered trail exactly.
  3. Re-crawl and confirm the head carries a BreadcrumbList with one item per level.
  • evidence capped at 25 of 38 pointers

Exposure80 / 100 · coverage 74%

Exposure findings
SeverityConfidenceStatusFindingAffectedSourceEvidence
ErrorCertainUnknownPlain HTTP does not redirect permanently to HTTPS1 plain-HTTP address(es) for this storefront answer without redirecting to HTTPS, so the site — and a shopper session on it — is reachable over an unencrypted connection.site-widerule

Plain HTTP does not redirect permanently to HTTPS

1 plain-HTTP address(es) for this storefront answer without redirecting to HTTPS, so the site — and a shopper session on it — is reachable over an unencrypted connection.

Affected
site-wide
Attributed to
cause not attributed
Rule
security/http-not-redirected
Source
rule

Evidence (2)

  • Site › hostHygiene.variants[1]4 fieldssite:hostHygiene.variants[1]
  • Site › host"www.deep-synthetic.example"site:host

Fix

Setup > SuiteCommerce Advanced > Set Up Web Site > Web Site record, the domain list and its HTTPS setting; then your DNS or CDNa configuration change

  1. Make every hostname on this domain serve HTTPS, including the apex.
  2. Redirect http:// to https:// with a 301 at the first hop.
  3. Re-check from outside your network that no plain-HTTP address answers 200.
WarningCertainUnknownThe storefront can be framed by another siteThe storefront sends neither X-Frame-Options nor a CSP frame-ancestors directive, so any site can load it in a frame and overlay it.site-widerule

The storefront can be framed by another site

The storefront sends neither X-Frame-Options nor a CSP frame-ancestors directive, so any site can load it in a frame and overlay it.

Affected
site-wide
Attributed to
cause not attributed
Rule
security/xfo-missing
Source
rule

Evidence (2)

  • Response header x-frame-optionsabsentsecurity:headers#x-frame-options
  • Response header content-security-policyabsentsecurity:headers#content-security-policy

Fix

A merchant-controlled CDN or reverse proxy in front of the storefront; NetSuite sends these headers on some releases and not othersa configuration change

  1. Add Content-Security-Policy: frame-ancestors 'self' — the modern directive, which browsers prefer over X-Frame-Options.
  2. Add X-Frame-Options: SAMEORIGIN alongside it for older browsers.
  3. If a partner legitimately frames the site, name their origin in frame-ancestors rather than leaving it open.
InfoCertainUnknownNo Content-Security-Policy is sentThe storefront sends no Content-Security-Policy. A useful one is hard here: the SSP application emits inline scripts and the templates bundle is evaluated at runtime, so a policy without unsafe-inline would break the site. This is recorded as context rather than as a defect.site-widerule

No Content-Security-Policy is sent

The storefront sends no Content-Security-Policy. A useful one is hard here: the SSP application emits inline scripts and the templates bundle is evaluated at runtime, so a policy without unsafe-inline would break the site. This is recorded as context rather than as a defect.

Affected
site-wide
Attributed to
cause not attributed
Rule
security/csp-missing
Source
rule

Evidence (1)

  • Response header content-security-policyabsentsecurity:headers#content-security-policy

Fix

A merchant-controlled CDN or reverse proxy in front of the storefront; NetSuite sends no CSP of its owna configuration change

  1. Start in report-only mode and collect violations for a week before enforcing anything.
  2. Begin with the directives that cost nothing on SuiteCommerce: frame-ancestors, object-src none, base-uri self.
  3. Treat script-src as a separate project: it needs every inline block the SSP application and the generator emit to be accounted for first.
InfoCertainUnknownPlatform: The NetSuite account id is reachable from the storefrontThe account id is reachable from the storefront: the CMS domain API names the NetSuite system domain, which carries it. This is NetSuite behaviour and there is no setting that suppresses it.site-widerule

Platform: The NetSuite account id is reachable from the storefront

The account id is reachable from the storefront: the CMS domain API names the NetSuite system domain, which carries it. This is NetSuite behaviour and there is no setting that suppresses it.

Affected
site-wide
Attributed to
NetSuite platform
Rule
exposure/system-domain
Source
rule

Evidence (2)

  • Discovery › siteDomain.systemDomain"https://1000001.app.netsuite.com/"discovery:siteDomain.systemDomain
  • Site › companyId"1000001"site:companyId

Fix

Nothing on the Web Site record changes this; the endpoint is a platform APIa configuration change

  1. Treat the account id as public when deciding what else may be keyed on it.
InfoLikelyUnknownThe public items API returns internal item fieldsThe public items API returns 2 operational field(s) for every item: isinactive, isonline. No commercial or cost field is exposed; confirm each of these is one you mean to publish.2 configuration keysrule

The public items API returns internal item fields

The public items API returns 2 operational field(s) for every item: isinactive, isonline. No commercial or cost field is exposed; confirm each of these is one you mean to publish.

Affected
2 configuration keys
Attributed to
cause not attributed
Rule
exposure/item-fields-internal
Source
rule

Evidence (2)

  • Catalog › internalLookingFields[0]"isinactive"catalog:internalLookingFields[0]
  • Catalog › internalLookingFields[1]"isonline"catalog:internalLookingFields[1]

Fix

Setup > SuiteCommerce Advanced > Set Up Web Site > Web Site record, the Search and Item Details fieldsets; field names come from Configuration > ItemsSearchAPIa configuration change

  1. Remove from the fieldset every field the storefront does not render — the API returns the whole fieldset to anonymous callers.
  2. Where a price level is genuinely needed for logged-in shoppers, rely on the personalised items endpoint rather than publishing it in the anonymous fieldset.
  3. Re-crawl and confirm the field is gone from the items response.
InfoCertainUnknownNo Referrer-Policy is declaredThe storefront declares no Referrer-Policy, so the browser default decides what is sent with every cross-origin request. Storefront URLs carry search terms, facet paths and session tokens.site-widerule

No Referrer-Policy is declared

The storefront declares no Referrer-Policy, so the browser default decides what is sent with every cross-origin request. Storefront URLs carry search terms, facet paths and session tokens.

Affected
site-wide
Attributed to
cause not attributed
Rule
security/referrer-policy-missing
Source
rule

Evidence (1)

  • Response header referrer-policyabsentsecurity:headers#referrer-policy

Fix

A merchant-controlled CDN or reverse proxy in front of the storefront; NetSuite sends no Referrer-Policya configuration change

  1. Send Referrer-Policy: strict-origin-when-cross-origin to make the current browser default explicit.
  2. Tighten to origin-when-cross-origin if any analytics vendor should not receive shopper search terms or facet paths.
  3. Check that nothing you rely on needs the full referrer before tightening further.
InfoCertainUnknownPlatform: No Strict-Transport-Security header is sentThe storefront sends no Strict-Transport-Security header, so a shopper who types the domain makes one interceptable plain-HTTP request before being redirected. NetSuite does not emit this header and no Web Site setting adds it.site-widerule

Platform: No Strict-Transport-Security header is sent

The storefront sends no Strict-Transport-Security header, so a shopper who types the domain makes one interceptable plain-HTTP request before being redirected. NetSuite does not emit this header and no Web Site setting adds it.

Affected
site-wide
Attributed to
NetSuite platform
Rule
security/hsts-missing
Source
rule

Evidence (1)

  • Response header strict-transport-securityabsentsecurity:headers#strict-transport-security

Fix

Nothing on the Web Site record adds this header; NetSuite does not emit ita configuration change

  1. Put a merchant-controlled CDN in front of the storefront if this matters to your risk assessment; that is the only place the header can be added.
  2. Make sure the plain-HTTP redirect to HTTPS is in place, which is what limits the exposure to a single request.

Content90 / 100 · coverage 84%

Content findings
SeverityConfidenceStatusFindingAffectedSourceEvidence
WarningCertainUnknownSampled items with no web-store image1 of the 13 sampled item(s) have no web-store image, so their product pages and every listing show the theme placeholder.1 item of 138%rule

Sampled items with no web-store image

1 of the 13 sampled item(s) have no web-store image, so their product pages and every listing show the theme placeholder.

Affected
1 item of 13
Attributed to
cause not attributed
Rule
catalog/no-image
Source
rule

Evidence (1)

  • Item 13hasImage = falsecatalog:item:13#hasImage

Fix

Item record › Web Store subtab › Item Images (the image folder per image type)a content change

  1. Attach a detail image to each item, in the image type the theme reads.
  2. Check that the image folder is marked Available Without Login.
  3. Re-crawl and confirm the product page no longer renders the placeholder.
WarningCertainUnknownLanding pages with no meta description2 of the 83 CMS landing page(s) have no meta description, so their search snippets are taken from the page layout.site-widerule

Landing pages with no meta description

2 of the 83 CMS landing page(s) have no meta description, so their search snippets are taken from the page layout.

Affected
site-wide
Attributed to
cause not attributed
Rule
cms/landing-meta-missing
Source
rule

Evidence (2)

  • CMS page cms-draft8 fieldscms:cms-draft
  • CMS page cms-last8 fieldscms:cms-last

Fix

Site Management Tools › the page › Settings › Meta Description (per page), not the content editora content change

  1. Open each page’s settings panel and write a one-sentence description.
  2. Start with the campaign and guide pages that are linked from the navigation.
  3. Check the page title in the same panel while you are there.
  4. Re-crawl and confirm the description is in the served head.
WarningCertainUnknownSampled items with an empty Meta Tag HTML field1 of the 13 sampled item(s) have an empty Meta Tag HTML field, so their product pages carry no meta description.1 item of 138%rule

Sampled items with an empty Meta Tag HTML field

1 of the 13 sampled item(s) have an empty Meta Tag HTML field, so their product pages carry no meta description.

Affected
1 item of 13
Attributed to
cause not attributed
Rule
catalog/metataghtml-missing
Source
rule

Evidence (1)

  • Item 13hasMeta = falsecatalog:item:13#hasMeta

Fix

Item record › Web Store subtab › Meta Tag HTMLa content change

  1. Put a `<meta name="description" content="…">` tag in the field, one per item.
  2. Describe the product in a sentence a shopper would read in a search result.
  3. Mass-update the affected items rather than editing them one by one.
  4. Re-crawl and confirm the PDP head carries the description.
InfoLikelyUnknownOut-of-stock items the site still publishes1 out-of-stock item(s) are still published by the site, so search engines and shoppers keep arriving at a product that cannot be bought.1 item of 138%rule

Out-of-stock items the site still publishes

1 out-of-stock item(s) are still published by the site, so search engines and shoppers keep arriving at a product that cannot be bought.

Affected
1 item of 13
Attributed to
cause not attributed
Rule
catalog/oos-indexable
Source
rule

Evidence (1)

  • Item 13isInStock = falsecatalog:item:13#isInStock

Fix

Item record › Web Store subtab (Display in Web Store), or the theme’s out-of-stock product page behavioura content change

  1. Decide per item: keep the page and offer a back-in-stock signup, or take it down.
  2. To keep it, make the out-of-stock state and the alternative obvious on the page.
  3. To take it down, clear Display in Web Store so the item leaves the sitemap.
  4. Never leave a bought-out seasonal item published with no alternative offered.

Performance98 / 100 · coverage 86%

Performance findings
SeverityConfidenceStatusFindingAffectedSourceEvidence
WarningCertainUnknownPlatform: Bundles served without a Cache-Control header4 of 4 bundle(s) are served without a Cache-Control header, so browsers re-download them on every page view.site-widerule

Platform: Bundles served without a Cache-Control header

4 of 4 bundle(s) are served without a Cache-Control header, so browsers re-download them on every page view.

Affected
site-wide
Attributed to
NetSuite platform
Rule
perf/no-cache-headers
Source
rule

Evidence (4)

  • core bundle1137 bytesbundle:core
  • css bundle393 bytesbundle:css
  • extensions bundle1950 bytesbundle:ext
  • templates bundle439 bytesbundle:tpl

Fix

The file cabinet folder each bundle is served from, and NetSuite support for the CDN cache policy on the SSP applicationa configuration change

  1. Confirm the response really carries no Cache-Control rather than a private one.
  2. Check whether the folder is served through the CDN at all.
  3. Raise it with NetSuite support: these headers are set platform-side.

Accessibility94 / 100 · coverage 100%

Accessibility findings
SeverityConfidenceStatusFindingAffectedSourceEvidence
WarningCertainUnknownSerious-impact accessibility violations14 serious accessibility violation(s) across 14 page(s), affecting 27 element(s): target-size (27 nodes).14 pages of 1878%rule

Serious-impact accessibility violations

14 serious accessibility violation(s) across 14 page(s), affecting 27 element(s): target-size (27 nodes).

Affected
14 pages of 18
Attributed to
cause not attributed
Rule
a11y/axe-serious
Source
rule

Evidence (14)

  • / (mobile) → a11y.violations[0]target-size (serious, 1 node) — a[href$="department-4"]render:p000:mobile#a11y.violations[0]
  • /department-1 (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-11"], a[href$="product-12"]render:p002:desktop#a11y.violations[0]
  • /department-1/custitem_colour/Grey (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-{{first}}"], a[href$="product-{{second}}"]render:p003:desktop#a11y.violations[0]
  • /department-1/custitem_colour/Grey/custitem_material/Paper/custitem_size/Small (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-{{first}}"], a[href$="product-{{second}}"]render:p004:desktop#a11y.violations[0]
  • /department-1/custitem_material/Paper (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-{{first}}"], a[href$="product-{{second}}"]render:p005:desktop#a11y.violations[0]
  • /department-1/custitem_size/Small (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-{{first}}"], a[href$="product-{{second}}"]render:p006:desktop#a11y.violations[0]
  • /department-2 (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-21"], a[href$="product-22"]render:p019:desktop#a11y.violations[0]
  • /department-3 (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-31"], a[href$="product-32"]render:p031:desktop#a11y.violations[0]
  • /department-4 (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-41"], a[href$="product-42"]render:p035:desktop#a11y.violations[0]
  • /guide-41 (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-41"], a[href$="product-410"]render:p039:desktop#a11y.violations[0]
  • /guide-65 (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-65"], a[href$="product-650"]render:p040:desktop#a11y.violations[0]
  • /guide-66 (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-66"], a[href$="product-660"]render:p041:desktop#a11y.violations[0]
  • /guide-69 (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-69"], a[href$="product-690"]render:p042:desktop#a11y.violations[0]
  • /search?keywords=Grey (desktop) → a11y.violations[0]target-size (serious, 2 nodes) — a[href$="product-{{first}}"], a[href$="product-{{second}}"]render:p058:desktop#a11y.violations[0]

Fix

The theme templates and extension views that render the named elementsa code change

  1. Open the selectors under each finding’s evidence; the axe rule id is beside them, so the same check can be re-run in a browser to confirm a fix.
  2. Start with the ones that repeat on every page: they are in a shared template.
  3. Walk the whole buying path with a keyboard afterwards.
  4. Re-crawl and compare the counts.

Platform95 / 100 · coverage 86%

Platform findings
SeverityConfidenceStatusFindingAffectedSourceEvidence
WarningCertainUnknownThe SSP application is a year or more behindThe storefront runs SuiteCommerce 2024.1.30, at least 4 release cycles behind 2026.1 — roughly 2.0 years of core fixes and features that are not on this site.site-widerule

The SSP application is a year or more behind

The storefront runs SuiteCommerce 2024.1.30, at least 4 release cycles behind 2026.1 — roughly 2.0 years of core fixes and features that are not on this site.

Affected
site-wide
Attributed to
cause not attributed
Rule
platform/release-behind
Source
rule

Evidence (2)

  • Site › release.normalised"2024.1.30"site:release.normalised
  • Site › releaseSource"RELEASE_METADATA"site:releaseSource

Fix

Setup > SuiteCommerce Advanced > Set Up Web Site, and the SSP application bundle at /app/a code change

  1. Read Oracle release notes from this release forward and list the core changes that touch the extensions and theme this site runs.
  2. Install the target release as a second SSP application in sandbox and point a test domain at it.
  3. Re-apply the theme and extension overrides against the new core, then re-run this scan against the sandbox domain before switching production.
InfoCertainUnknownThe extensions this storefront shipsThe storefront ships 2 extensions from 1 vendor(s).2 modulesrule

The extensions this storefront ships

The storefront ships 2 extensions from 1 vendor(s).

Affected
2 modules
Attributed to
cause not attributed
Rule
platform/extension-inventory
Source
rule

Evidence (2)

  • Synthetic.Menus.2.1.02 modulesext:Synthetic.Menus.2.1.0
  • Synthetic.Wishes.1.0.01 modulesext:Synthetic.Wishes.1.0.0

Fix

Commerce > Extensions > Extension Manager, the activation list for this domaina configuration change

  1. Check the list against the extensions you believe are in use on this domain.
  2. De-activate anything no longer needed: an inactive extension still ships its JavaScript until it is removed from the activation list.

Platform

Release
2024.1.30
Release label
SCA_2024.1.30
Release family
modern
Release confidence
certain
NetSuite version
not found
SSP application
not found
SSP application fork
none — the stock NetSuite application
Legacy profile
no
Extensions
2
Extensions (2)
ExtensionVersionMounted
Synthetic.Menus2.1.0yes
Synthetic.Wishes1.0.0yes

A wrapper that is present but not observed mounting is installed and inert on the pages this audit read.

Catalog and content

Catalog — 13 items sampled of 13 reported
MeasureItems
URL component carries a duplicate suffix0
Page Title duplicated across items0
URL component duplicated across items0
inactive or not published to the web store0
matrix parent without meta0
no Meta Tag HTML1
no Page Title0
no image1
out of stock and still indexable1
URL component is the SKU0
thin or absent description0
Categories
MeasureCount
Categories in the tree52
Enriched through the API1
Enriched without a meta description0
Enriched and not displayed in the site0
CMS pages
MeasureCount
Pages83
Drafts1
Without a meta description2

Pages

Pages crawled (60). First byte is what the crawler's own fetch measured, which forces a fresh render and is not a returning shopper's.
PageTypeStatusFirst byte (our fetch)PrerenderTitleCanonicalH1Words
/home20040 msDeep Synthetic Store/148
/Department-1other40440 msPage not found | Deep Synthetic Storeabsent112
/department-1category20040 msDepartment 1 | Deep Synthetic Store/department-1122
/department-1/custitem_colour/Greyfacet20040 ms{{title}} | Deep Synthetic Store/121
/department-1/custitem_colour/Grey/custitem_material/Paper/custitem_size/Smallfacet20040 ms{{title}} | Deep Synthetic Store/121
/department-1/custitem_material/Paperfacet20040 ms{{title}} | Deep Synthetic Store/121
/department-1/custitem_size/Smallfacet20040 ms{{title}} | Deep Synthetic Store/121
/department-1/section-1category20040 msSection 1.1 | Deep Synthetic Store/department-1/section-1122
/department-1/section-1/aisle-1category20040 msAisle 1.1.1 | Deep Synthetic Store/department-1/section-1/aisle-1122
/department-1/section-1/aisle-2category20040 msAisle 1.1.2 | Deep Synthetic Store/department-1/section-1/aisle-2122
/department-1/section-1/aisle-3category20040 msAisle 1.1.3 | Deep Synthetic Store/department-1/section-1/aisle-3122
/department-1/section-2category20040 msSection 1.2 | Deep Synthetic Store/department-1/section-2122
/department-1/section-2/aisle-1category20040 msAisle 1.2.1 | Deep Synthetic Store/department-1/section-2/aisle-1122
/department-1/section-2/aisle-2category20040 msAisle 1.2.2 | Deep Synthetic Store/department-1/section-2/aisle-2122
/department-1/section-2/aisle-3category20040 msAisle 1.2.3 | Deep Synthetic Store/department-1/section-2/aisle-3122
/department-1/section-3category20040 msSection 1.3 | Deep Synthetic Store/department-1/section-3122
/department-1/section-3/aisle-1category20040 msAisle 1.3.1 | Deep Synthetic Store/department-1/section-3/aisle-1122
/department-1/section-3/aisle-2category20040 msAisle 1.3.2 | Deep Synthetic Store/department-1/section-3/aisle-2122
/department-1/section-3/aisle-3category20040 msAisle 1.3.3 | Deep Synthetic Store/department-1/section-3/aisle-3122
/department-2category20040 msDepartment 2 | Deep Synthetic Store/department-2122
/department-2/section-1category20040 msSection 2.1 | Deep Synthetic Store/department-2/section-1122
/department-2/section-1/aisle-1category20040 msAisle 2.1.1 | Deep Synthetic Store/department-2/section-1/aisle-1122
/department-2/section-1/aisle-2category20040 msAisle 2.1.2 | Deep Synthetic Store/department-2/section-1/aisle-2122
/department-2/section-1/aisle-3category20040 msAisle 2.1.3 | Deep Synthetic Store/department-2/section-1/aisle-3122
/department-2/section-2category20040 msSection 2.2 | Deep Synthetic Store/department-2/section-2122
/department-2/section-2/aisle-1category20040 msAisle 2.2.1 | Deep Synthetic Store/department-2/section-2/aisle-1122
/department-2/section-2/aisle-2category20040 msAisle 2.2.2 | Deep Synthetic Store/department-2/section-2/aisle-2122
/department-2/section-2/aisle-3category20040 msAisle 2.2.3 | Deep Synthetic Store/department-2/section-2/aisle-3122
/department-2/section-3category20040 msSection 2.3 | Deep Synthetic Store/department-2/section-3122
/department-2/section-3/aisle-1category20040 msAisle 2.3.1 | Deep Synthetic Store/department-2/section-3/aisle-1122
/department-2/section-3/aisle-2category20040 msAisle 2.3.2 | Deep Synthetic Store/department-2/section-3/aisle-2122
/department-3category20040 msDepartment 3 | Deep Synthetic Store/department-3122
/department-3/section-1category20040 msSection 3.1 | Deep Synthetic Store/department-3/section-1122
/department-3/section-2category20040 msSection 3.2 | Deep Synthetic Store/department-3/section-2122
/department-3/section-3category20040 msSection 3.3 | Deep Synthetic Store/department-3/section-3122
/department-4category20040 msDepartment 4 | Deep Synthetic Store/department-4122
/department-4/section-1category20040 msSection 4.1 | Deep Synthetic Store/department-4/section-1122
/department-4/section-2category20040 msSection 4.2 | Deep Synthetic Store/department-4/section-2122
/department-4/section-3category20040 msSection 4.3 | Deep Synthetic Store/department-4/section-3122
/guide-41landing20040 msGuide 41 | Deep Synthetic Store/guide-41122
/guide-65landing20040 msGuide 65 | Deep Synthetic Store/guide-65122
/guide-66landing20040 msGuide 66 | Deep Synthetic Store/guide-66122
/guide-69landing20040 msGuide 69 | Deep Synthetic Store/guide-69122
/product-1pdp20040 msProduct 1 | Deep Synthetic Store/product-1118
/product-10pdp20040 msProduct 10 | Deep Synthetic Store/product-10118
/product-100pdp20040 msProduct 100 | Deep Synthetic Store/product-100118
/product-101pdp20040 msProduct 101 | Deep Synthetic Store/product-101118
/product-102pdp20040 msProduct 102 | Deep Synthetic Store/product-102118
/product-103pdp20040 msProduct 103 | Deep Synthetic Store/product-103118
/product-104pdp20040 msProduct 104 | Deep Synthetic Store/product-104118
/product-105pdp20040 msProduct 105 | Deep Synthetic Store/product-105118
/product-106pdp20040 msProduct 106 | Deep Synthetic Store/product-106118
/product-107pdp20040 msProduct 107 | Deep Synthetic Store/product-107118
/product-108pdp20040 msProduct 108 | Deep Synthetic Store/product-108118
/product-109pdp20040 msProduct 109 | Deep Synthetic Store/product-109118
/product-11pdp20040 msProduct 11 | Deep Synthetic Store/product-11118
/product-110pdp20040 msProduct 110 | Deep Synthetic Store/product-110118
/product-111pdp20040 msProduct 111 | Deep Synthetic Store/product-111118
/search?keywords=Greysearch20040 ms{{title}} | Deep Synthetic Store/121
/this-page-does-not-exist-8c3dcdd1notfound40440 msPage not found | Deep Synthetic Storeabsent112

What we could not check

39 checks did not run, and 12 stages of the crawl did not run

Stages that did not run

  • discover category details: 16 of 52 categories enriched at depth standard
  • discover items api: no items call was observed; the url was constructed from the environment
  • render:https://www.deep-synthetic.example/ rendered, but not compared against the prerendered HTML — parity is measured on the desktop pass only
  • render:https://www.deep-synthetic.example/department-1 rendered, but not compared against the prerendered HTML — parity is measured on the desktop pass only
  • render:https://www.deep-synthetic.example/department-2 rendered, but not compared against the prerendered HTML — parity is measured on the desktop pass only
  • render:https://www.deep-synthetic.example/department-3 rendered, but not compared against the prerendered HTML — parity is measured on the desktop pass only
  • render:https://www.deep-synthetic.example/department-4 rendered, but not compared against the prerendered HTML — parity is measured on the desktop pass only
  • render:https://www.deep-synthetic.example/product-1 rendered, but not compared against the prerendered HTML — parity is measured on the desktop pass only
  • render:https://www.deep-synthetic.example/product-10 rendered, but not compared against the prerendered HTML — parity is measured on the desktop pass only
  • render:https://www.deep-synthetic.example/product-100 rendered, but not compared against the prerendered HTML — parity is measured on the desktop pass only
  • render:https://www.deep-synthetic.example/product-101 rendered, but not compared against the prerendered HTML — parity is measured on the desktop pass only
  • render:https://www.deep-synthetic.example/search?keywords=Grey rendered, but not compared against the prerendered HTML — parity is measured on the desktop pass only

RELEASE_METADATA carries no ns_version; the account version cannot be compared against the cached environment

  • The cached environment names the NetSuite version the account runs platform/ns-version-skew

the environment script carries no themeAssetsPath, so the theme vendor, name and version are unknown and template findings stay unattributed

  • The active theme is identified platform/theme-inventory

the storefront sent no sspappcontext header, so the SSP application could not be read from the response

  • The sspappcontext header is recorded platform/ssp-context-header

the storefront sent no sspappcontext header, so the SSP application folder could not be derived and nothing was requested

  • The SSP backend library is not readable by strangers platform/ssp-library-readable

the extensions bundle answered without a Last-Modified header, so the build stamp has nothing to be compared against

  • The ?t= cache buster is no older than the extension bundle it busts platform/build-stamp-stale

0 extension service endpoint(s) were harvested from the bundle and none was requested: this crawl makes no call to a merchant service, so no response body exists to check for a stack trace or SQL text

  • No extension service answers an error with internal detail exposure/service-verbose-error

0 extension service endpoint(s) are referenced by this storefront and none was called: deciding whether an endpoint accepts an anonymous POST requires sending one, which is a write against the merchant’s account rather than an observation of it, and the ServiceController permissions that would answer it from outside are server-side

  • Extension services that accept an anonymous write are inventoried exposure/service-cross-origin

the rendered captures record request counts and hosts but not request bodies or the consent-banner state, so whether telemetry carried shopper PII before consent could not be decided — this needs a capture that retains the ElasticLogger POST body and the banner’s accepted state

  • No shopper PII reaches telemetry before consent is given exposure/sensors-pii-before-consent

the tag-manager data layer is merged into the browser by the user environment service rather than written into the cached environment script, and the rendered captures do not retain that merged object — so what the data layer holds for a guest could not be read

  • No shopper PII in the tag-manager data layer for a guest exposure/gtm-datalayer-pii

no sspappcontext header, so no SSP library path could be derived

  • The SSP bundle carries only this domain’s configuration exposure/ssp-config-other-domain

the home document set no cookies: it was served from the prerender cache, which correctly carries no Set-Cookie, so the flags on the session cookies a real shopper receives were not observed

  • Cookies the storefront sets are Secure and HttpOnly security/cookie-flags

deciding whether deep-synthetic.example and www.deep-synthetic.example disagree needs both probed over https, and this crawl probed 1 of them — the hygiene probes are the apex over https and the site host over http, so the two are never compared

  • The apex and www agree on one canonical host security/apex-www-inconsistent

no crawled page carries rel=prev or rel=next, so there is no pagination sequence to check — crawl a category deep enough to reach its second page

  • rel=prev/next on a paged list is an absolute URL seo/pagination-rel

no home or product page in this crawl emits an Open Graph card, so there is no card to check for completeness

  • Pages that emit an Open Graph card fill og:title, og:description and og:image social/og-basic-missing

no page in this crawl emits an Open Graph card, so there is no value to check for a templating placeholder that reached production

  • Open Graph tags carry real values, not the string "undefined" social/og-value-undefined

no page in this crawl emits an og:image, so there is no image URL to check the shape of

  • og:image is an absolute http(s) URL social/og-image-malformed

no page outside search and the 404 route emits an og:url, so there is no share address to check

  • og:url carries no query parameters social/og-url-has-params

no page in this crawl emits an og:image, so there is no image to reach for

  • The og:image returns 200 social/og-image-unreachable

no page in this crawl emits a twitter:card, so there is no card to complete

  • Twitter cards name twitter:site and twitter:creator social/twitter-card-incomplete

no page in this crawl was confirmed as a product page by the generator’s own fieldset=details items call, so there is no product markup to look for

  • Product pages carry Product structured data structured/product-missing

the home page publishes no Organization node

  • The Organization node carries the brand name, not the page title structured/organization-name-is-title

no page in this crawl carried a prerender debug block; the timings, sub-requests and cache lines this check reads are only in that block — re-run the crawl so the debug request lands, or check whether the storefront strips the parameter

  • The prerender pass completes in under five seconds prerender/slow-generation

every page with a prerender debug block in this crawl returned a non-200 status, and on those the generator’s own failed lookups are how it discovered the page does not exist — re-run the crawl so a page that returns 200 carries a debug block

  • Every first-party sub-request of the prerender pass returns 200 prerender/subrequest-failed
  • Third-party calls made during the prerender pass return 200 prerender/third-party-subrequest-failed
  • No sub-request of the prerender pass takes over a second prerender/subrequest-slow
  • The prerendered document is stored in the cache prerender/cache-not-stored
  • The prerender pass throws nothing and renders content prerender/generator-js-error

neither a page debug block nor the footer comment carried the SQL timing sentinel in this crawl, so there is nothing to read a slow query from

  • The prerender pass runs no query slower than 100 ms prerender/slow-sql

the sitemap was found through the robots.txt Sitemap: line, so the crawler never requested /sitemap.xml and cannot say whether the conventional location serves one

  • The sitemap is reachable at /sitemap.xml discovery/sitemap-not-at-root

the pack records how many sitemap entries carry a lastmod (400 of 401) and never the dates themselves, so an age cannot be computed from it

  • Sitemap lastmod dates are current discovery/sitemap-lastmod-stale

the category API does not return the displayinsite flag — the crawler asks for it in every request and no response on any validated site has carried it, including all 1 categories enriched here — and without it a category the merchant hid deliberately cannot be told from one left unlinked by accident. This check needs that flag from another source before it can run on any site

  • Categories meant to be visible are linked from the site discovery/orphan-category

the items sample records only whether Meta Tag HTML is present, not whether it parses as <meta> tags — the crawler never keeps the blob, so malformed-ness cannot be distinguished from well-formed in this pack

  • The Meta Tag HTML field parses as <meta> tags catalog/metataghtml-malformed

the items sample carries no matrix parent-or-child marker and nothing joins a sitemap URL back to the item that produced it, so a child with its own URL cannot be distinguished from a standalone item in this pack

  • Matrix children do not get their own indexable URL catalog/matrix-child-exposed

the pack carries CMS page records but no CMS_HTML content bodies — the content endpoint is read to classify page types and its bodies are never stored, so inline scripts inside content blocks cannot be seen in this pack

  • CMS HTML content carries no inline <script> cms/html-content-inline-script

the pack carries CMS page records but no CMS_HTML content bodies, so images inside content blocks on pages the crawl did not fetch cannot be inspected — the alt-text census of the fetched pages is reported by the a11y checks

  • Images inside CMS HTML content carry alt text cms/html-content-img-no-alt

the pack carries no per-module member surface (ids and hashes only); member diffing needs the stored bundle bodies, which this check does not read yet

  • Core modules export the members their release exports core/member-mismatch

the behavioural harness did not run on this crawl; every behaviour check reports nothing — run a deep crawl to include it

  • Every component an extension asks for exists on this site component/availability

the headless pass recorded no Interaction to Next Paint for any rendered page — a lab run measures it only when an interaction happened

  • Interaction to Next Paint on the rendered pages perf/inp

render-blocking cost cannot be estimated: it came from the render-blocking-resources Lighthouse audit, ADR-007 removed Lighthouse and nothing has written that field since, and the pack does not carry the page’s script tags in document order either. This check cannot run on any crawl until one of those two changes

  • Resources that delay the first paint perf/render-blocking

A skipped check is not a pass. It is a gap, and it is counted in the coverage above.

Want this for your own storefront? See the plans, or verify a domain and take the free audit.