Features
Every check Arachne runs, with its source and fix
110 checks in 5 categories. 77 follow a published source; the other 33 are heuristics, labelled as such and never critical. 29 of them look across the whole site rather than one page.
SEO
76 checks · 10 groups
Titles, social cards, indexing, canonicals, links, sitemaps, hreflang, structured data, and JavaScript rendering.
Titles and descriptions
8 checksThe title and description each page shows in search results.
MISSING_TITLE
criticalDocumentedEvery page
Page has no non-empty title
Fix: Add a unique
Source: developers.google.com(opens in a new tab)<title>in the head that names the page's content, for example<title>Pricing · Acme</title>.DUPLICATE_TITLE
warningDocumentedAcross the site
Fix: Give each indexable page its own title; when pages share a template, build the title from the page's own subject (product name, article headline).
Source: developers.google.com(opens in a new tab)TITLE_TOO_SHORT
infoHeuristicEvery page
Title is 5 Unicode characters; target range is 15–60
Fix: Make the title describe the page specifically, such as the product name plus what it is, instead of a single word or the brand alone.
Source: developers.google.com(opens in a new tab)TITLE_TOO_LONG
infoHeuristicEvery page
Title is 855 px wide in Google's result font; about 600 px fit, so it shows as "TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT…"
Fix: Move the page-specific words to the start and trim the rest; Google cuts titles by pixel width, so anything after the cut point is not shown.
Source: developers.google.com(opens in a new tab)MISSING_META_DESC
infoDocumentedEvery page
Page has no non-empty meta description
Fix: Add
Source: developers.google.com(opens in a new tab)<meta name="description" content="…">with an accurate one- or two-sentence summary of the page.META_DESC_TOO_SHORT
infoHeuristicEvery page
Meta description is 16 Unicode characters; target range is 50–160
Fix: Expand the description into a full sentence that says what the visitor will find on the page.
Source: developers.google.com(opens in a new tab)META_DESC_TOO_LONG
infoHeuristicEvery page
Meta description is 2022 px wide in Google's result font; about 920 px fit, so it shows as "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD…"
Fix: Put the key information in the first sentence; snippets are cut by pixel width, so the end may not be shown.
Source: developers.google.com(opens in a new tab)DUPLICATE_META_DESC
infoDocumentedAcross the site
Fix: Write a description for each important page, or leave it out so Google builds a snippet from the page; don't repeat one description site-wide.
Source: developers.google.com(opens in a new tab)
Open Graph and social cards
13 checksHow links to the site look when shared on social networks and in chat apps.
OG_URL_MISMATCH
warningHeuristicEvery page
Open Graph URL does not match the rendered page
Fix: Set
Source: ogp.me(opens in a new tab)og:urlto the same URL as the canonical, so shares are counted against one address.INVALID_OG_URL
warningDocumentedEvery page
Open Graph URL is not an absolute HTTP(S) URL
Fix: Use an absolute
Source: ogp.me(opens in a new tab)https://URL inog:url.LOCAL_OG_URL
warningDocumentedEvery page
Open Graph URL points to a local address
Fix: Replace the localhost or private address in
Source: ogp.me(opens in a new tab)og:urlwith the public URL; it is usually a build-time environment variable left at its default.INVALID_OG_IMAGE_URL
warningDocumentedEvery page
Open Graph image is not an absolute HTTP(S) URL
Fix: Use an absolute
Source: ogp.me(opens in a new tab)https://URL inog:image; relative paths are not resolved by most link-preview crawlers.LOCAL_OG_IMAGE_URL
warningDocumentedEvery page
Open Graph image points to a local address
Fix: Replace the localhost or private address in
Source: ogp.me(opens in a new tab)og:imagewith the public image URL.INVALID_X_IMAGE_URL
warningDocumentedEvery page
X Card image URL is invalid
Fix: Use an absolute
Source: developer.x.com(opens in a new tab)https://URL fortwitter:image.LOCAL_X_IMAGE_URL
warningDocumentedEvery page
X Card image points to a local address
Fix: Replace the localhost or private address in
Source: developer.x.com(opens in a new tab)twitter:imagewith the public image URL.MISSING_OG_TITLE
infoHeuristicEvery page
Page has no Open Graph title
Fix: Add
Source: ogp.me(opens in a new tab)<meta property="og:title" content="…">so shared links show a proper title.MISSING_OG_DESCRIPTION
infoHeuristicEvery page
Page has no Open Graph description
Fix: Add
Source: ogp.me(opens in a new tab)<meta property="og:description" content="…">with a one-sentence summary for link previews.MISSING_OG_IMAGE
infoHeuristicEvery page
Page has no Open Graph image
Fix: Add
Source: ogp.me(opens in a new tab)<meta property="og:image" content="https://…">with an absolute URL to an image of at least 1200×630.MISSING_OG_URL
infoHeuristicEvery page
Page has no Open Graph URL
Fix: Add
Source: ogp.me(opens in a new tab)<meta property="og:url" content="…">with the page's canonical URL.MISSING_X_CARD
infoHeuristicEvery page
Page has no twitter:card declaration
Fix: Add
Source: developer.x.com(opens in a new tab)<meta name="twitter:card" content="summary_large_image">; X falls back to Open Graph for the title, description, and image.INCOMPLETE_X_CARD
infoHeuristicEvery page
X Card metadata is incomplete
Fix: Add the missing card fields, or the Open Graph equivalents X falls back to.
Source: developer.x.com(opens in a new tab)
Indexing and canonicals
16 checksWhether search engines may index each page, and which URL they treat as the original.
CANONICAL_TARGET_NOINDEX
criticalDocumentedAcross the site
Fix: Remove
Source: developers.google.com(opens in a new tab)noindexfrom the canonical target, or canonicalize to a page that can be indexed; together they tell Google to index nothing.SEARCH_CRAWLER_BLOCKED
criticalDocumentedAcross the site
Fix: Allow Googlebot and Bingbot in robots.txt; a
Source: developers.google.com(opens in a new tab)Disallow: /for them, or for*without an exception, removes the site from search.MULTIPLE_CANONICAL
warningDocumentedEvery page
Page declares multiple canonical URLs
Fix: Keep exactly one canonical link; check for a second one added by a plugin, a CMS, or client-side code.
Source: developers.google.com(opens in a new tab)INVALID_CANONICAL
warningDocumentedEvery page
Page canonical URL is invalid
Fix: Use an absolute
Source: developers.google.com(opens in a new tab)httporhttpsURL in the canonicalhref.CANONICAL_MISMATCH
warningDocumentedEvery page
Page canonical points to another URL
Fix: Confirm the canonical target is the page you want indexed; if this page is the preferred one, point the canonical at itself.
Source: developers.google.com(opens in a new tab)CANONICAL_TARGET_BROKEN
warningDocumentedAcross the site
Fix: Point the canonical at a live page that returns 200, usually the page itself.
Source: developers.google.com(opens in a new tab)CANONICAL_TARGET_REDIRECTS
warningDocumentedAcross the site
Fix: Point the canonical at the final URL the redirect lands on.
Source: developers.google.com(opens in a new tab)CANONICAL_CHAIN
warningDocumentedAcross the site
Fix: Point every canonical straight at the final preferred page instead of at a page that names another canonical.
Source: developers.google.com(opens in a new tab)SOFT_404
warningDocumentedAcross the site
Fix: Return a real 404 or 410 status for pages that don't exist, even when you show a friendly not-found page.
Source: developers.google.com(opens in a new tab)HTTP_NOT_REDIRECTED
warningDocumentedAcross the site
Fix: Redirect every
Source: developers.google.com(opens in a new tab)http://URL to itshttps://version with a 301 or 308.HOST_VARIANTS_NOT_CONSOLIDATED
warningDocumentedAcross the site
Fix: Pick
Source: developers.google.com(opens in a new tab)wwwor the bare domain and redirect the other to it with a 301, so the site has one host.HOST_VARIANT_BROKEN
warningHeuristicAcross the site
Fix: Make the other host load and redirect it here with a 301: serve a valid HTTPS certificate for it and fix its error response, or remove its DNS record if it isn't meant to exist.
Source: developers.google.com(opens in a new tab)NOINDEX_DETECTED
infoDocumentedEvery page
Page has a noindex robots directive
Fix: If this page should appear in search, remove
Source: developers.google.com(opens in a new tab)noindexfrom the meta robots tag and theX-Robots-Tagheader; if not, keep it and remove the page from the sitemap.MISSING_CANONICAL
infoDocumentedEvery page
Page has no canonical URL
Fix: Add
Source: developers.google.com(opens in a new tab)<link rel="canonical" href="…">pointing at the page's preferred absolute URL, usually itself.OFFSITE_CANONICAL
infoDocumentedAcross the site
Fix: Confirm the cross-domain canonical is intended, as for syndicated content; otherwise point it at this site's own URL.
Source: developers.google.com(opens in a new tab)AI_CRAWLERS_BLOCKED
infoDocumentedAcross the site
Fix: Nothing to fix if this is intended; otherwise allow the AI crawlers you want in robots.txt. Blocking Google-Extended doesn't affect Google Search.
Source: platform.openai.com(opens in a new tab)
Links and status codes
10 checksBroken pages, redirects, and how pages link to each other.
SERVER_ERROR
criticalDocumentedEvery page
Page returned HTTP 503
Fix: Check the server logs for this URL; a persistent 5xx makes search engines crawl less and eventually drop the page.
Source: developers.google.com(opens in a new tab)CLIENT_ERROR
criticalDocumentedEvery page
Page returned HTTP 404
Fix: Restore the page, redirect it with a 301 to its replacement, or remove the links pointing at it.
Source: developers.google.com(opens in a new tab)REDIRECT_CHAIN
warningDocumentedEvery page
Page follows 2 redirects
Fix: Point the first URL straight at the final destination with a single 301, and update internal links to the final URL.
Source: developers.google.com(opens in a new tab)BROKEN_INTERNAL_LINKS
warningDocumentedAcross the site
Fix: Update or remove links to pages that return 4xx or 5xx, or restore the pages; redirect removed pages to their replacements.
Source: developers.google.com(opens in a new tab)GENERIC_ANCHOR_TEXT
infoDocumentedEvery page
1 internal link(s) have generic text: "click here" to /pricing
Fix: Write link text that says where the link goes, such as "Compare pricing plans" instead of "click here".
Source: developers.google.com(opens in a new tab)INTERNAL_NOFOLLOW
infoDocumentedEvery page
1 link(s) to this site are marked nofollow: /login
Fix: Remove
Source: developers.google.com(opens in a new tab)rel="nofollow"from links to your own pages; to keep a page out of search, usenoindexon that page instead.HOST_VARIANT_LINKS
infoDocumentedEvery page
1 link(s) point at this site under another scheme or host: http://www.example.com/pricing
Fix: Link to the site's preferred scheme and host everywhere, such as
Source: developers.google.com(opens in a new tab)https://www.example.com/…, and redirect the other variants to it with a 301.INTERNAL_LINKS_TO_REDIRECTS
infoDocumentedAcross the site
Fix: Change internal links to point at the final URL, so visitors and crawlers skip the redirect.
Source: developers.google.com(opens in a new tab)DEEP_PAGES
infoHeuristicAcross the site
Fix: Link important pages from hubs, category pages, or the navigation so they are within a few clicks of the home page.
Source: developers.google.com(opens in a new tab)ORPHAN_PAGES
infoHeuristicAcross the site
Fix: Link to each sitemap page from at least one crawled page, or remove pages nobody should reach.
Source: developers.google.com(opens in a new tab)
Sitemap
4 checksWhether the XML sitemap lists the live, canonical pages and only those.
SITEMAP_ERRORS
warningDocumentedAcross the site
Fix: Remove URLs that return errors from the sitemap, or fix the pages; a sitemap should list only live, indexable pages.
Source: developers.google.com(opens in a new tab)SITEMAP_CANONICALIZED
warningDocumentedAcross the site
Fix: List only canonical URLs in the sitemap; replace each entry with the URL its canonical names.
Source: developers.google.com(opens in a new tab)SITEMAP_REDIRECTS
infoDocumentedAcross the site
Fix: List the final URL in the sitemap instead of one that redirects.
Source: developers.google.com(opens in a new tab)MISSING_FROM_SITEMAP
infoDocumentedAcross the site
Fix: Add indexable pages to the sitemap, ideally from the same source that generates the pages.
Source: developers.google.com(opens in a new tab)
URL structure
3 checksURLs that create duplicates or endless variations for crawlers.
SESSION_IDS_IN_URLS
warningDocumentedAcross the site
Fix: Keep session state in cookies instead of URLs; session IDs create endless duplicate URLs for crawlers.
Source: developers.google.com(opens in a new tab)CRAWL_TRAP
warningHeuristicAcross the site
Fix: Stop crawlers from following the generated URLs: link filters with
Source: developers.google.com(opens in a new tab)rel="nofollow"or JavaScript, disallow the parameters in robots.txt, or cap the depth of generated paths.UPPERCASE_URLS
infoHeuristicAcross the site
Fix: Use lowercase URLs and redirect mixed-case variants, since most servers treat case as different pages.
Source: developers.google.com(opens in a new tab)
Languages (hreflang)
5 checksThe links between language and region versions of a page.
INVALID_HREFLANG
warningDocumentedEvery page
One or more hreflang declarations are invalid
Fix: Use ISO 639-1 language codes (optionally with an ISO 3166-1 region, such as
Source: developers.google.com(opens in a new tab)en-GB) orx-default, with absolute URLs.DUPLICATE_HREFLANG
warningDocumentedEvery page
A language is declared more than once in this hreflang set
Fix: Keep one hreflang link per language and region pair.
Source: developers.google.com(opens in a new tab)MISSING_HREFLANG_SELF_REFERENCE
warningDocumentedEvery page
Hreflang declarations do not include this rendered page
Fix: Add a hreflang link for this page's own language that points at this page.
Source: developers.google.com(opens in a new tab)HREFLANG_NOT_RECIPROCAL
warningDocumentedAcross the site
Fix: Make each alternate link back: every page in a hreflang set must list all the others, including itself.
Source: developers.google.com(opens in a new tab)HREFLANG_TO_NON_INDEXABLE
warningDocumentedAcross the site
Fix: Point hreflang alternates only at indexable pages that return 200 and are their own canonical.
Source: developers.google.com(opens in a new tab)
Structured data
4 checksJSON-LD markup and its eligibility for rich results.
MALFORMED_STRUCTURED_DATA
criticalDocumentedEvery page
Malformed JSON-LD: EOF while parsing
Fix: Fix the JSON syntax in the
Source: developers.google.com(opens in a new tab)application/ld+jsonblock; a single trailing comma or unescaped quote makes the whole block unreadable.INVALID_STRUCTURED_DATA
warningDocumentedEvery page
JSON-LD is missing @type
Fix: Add
Source: developers.google.com(opens in a new tab)@context: "https://schema.org"and an@typeto each JSON-LD item.STRUCTURED_DATA_MISSING_REQUIRED
warningDocumentedEvery page
Product structured data is missing required property: offers or review or aggregateRating
Fix: Add the required properties listed in the evidence; without them the item is not eligible for its rich result.
Source: developers.google.com(opens in a new tab)DEPRECATED_STRUCTURED_DATA
infoDocumentedEvery page
Page uses HowTo structured data; HowTo rich results are no longer shown
Fix: HowTo rich results were removed and FAQ results only show for authoritative government and health sites; keep the markup only if it serves another purpose.
Source: developers.google.com(opens in a new tab)
JavaScript rendering
5 checksDifferences between the HTML the server sends and the page after JavaScript runs.
NOINDEX_REMOVED_BY_JS
criticalDocumentedEvery page
The server HTML has a noindex meta robots tag that JavaScript removes
Fix: Remove
Source: developers.google.com(opens in a new tab)noindexfrom the server HTML itself; when Google seesnoindexbefore rendering, it may skip rendering and never see JavaScript remove it.RENDERED_ONLY_LINKS
warningDocumentedEvery page
10 of 10 internal links exist only after JavaScript runs
Fix: Render navigation and important internal links as
Source: developers.google.com(opens in a new tab)<a href>in the server HTML, so crawlers find them without running JavaScript.CANONICAL_CHANGED_BY_JS
warningDocumentedEvery page
JavaScript changes the canonical from /original to /
Fix: Set the canonical once in the server HTML; don't let JavaScript change it to a different URL.
Source: developers.google.com(opens in a new tab)NOINDEX_ADDED_BY_JS
warningDocumentedEvery page
JavaScript adds a noindex meta robots tag the server HTML doesn't have
Fix: If the page should not be indexed, put
Source: developers.google.com(opens in a new tab)noindexin the server HTML; if it should be, find the script that adds it.RENDERED_ONLY_CONTENT
infoDocumentedEvery page
The server HTML has 20 words; the rendered page has 500
Fix: Server-render or pre-render the main content; Google renders JavaScript later than it crawls, and other crawlers often don't render it at all.
Source: developers.google.com(opens in a new tab)
Mobile and app (PWA)
7 checksThe mobile viewport, icons, and the web app manifest used to install the site.
MISSING_VIEWPORT
warningDocumentedEvery page
Page has no viewport meta tag
Fix: Add
Source: developers.google.com(opens in a new tab)<meta name="viewport" content="width=device-width, initial-scale=1">to the head.INVALID_WEB_MANIFEST
warningDocumentedEvery page
The web app manifest /manifest.webmanifest has no start_url, display
Fix: Serve the linked manifest with a 200 status as valid JSON, with
Source: developer.mozilla.org(opens in a new tab)name(orshort_name),icons,start_url, anddisplay.MANIFEST_ICONS_TOO_SMALL
warningDocumentedEvery page
The web app manifest /manifest.webmanifest has no 512×512 icon; the largest regular icon is 192px
Fix: Add 192×192 and 512×512 PNG icons to the manifest's
Source: web.dev(opens in a new tab)icons, each with a matchingsizesvalue; Android uses them for the home screen and the splash screen.MISSING_FAVICON
warningDocumentedEvery page
The page links no icon and /favicon.ico is not served
Fix: Add
Source: developers.google.com(opens in a new tab)<link rel="icon" href="/favicon.svg">(or a square PNG of at least 48×48) to the head; Google shows it next to the site's results, and browsers show it in tabs and bookmarks.MISSING_WEB_MANIFEST
infoDocumentedEvery pageHidden by default
The page links no web app manifest
Fix: Only if the site should be installable: add
Source: web.dev(opens in a new tab)<link rel="manifest" href="/manifest.webmanifest">pointing at a manifest withname,icons,start_url, anddisplay.MISSING_THEME_COLOR
infoDocumentedEvery page
The page has a web app manifest but no theme-color meta tag; the manifest's theme_color is #0b5fff
Fix: Add
Source: developer.mozilla.org(opens in a new tab)<meta name="theme-color" content="#…">with the manifest'stheme_color, so the browser toolbar and the installed app use the brand color.MISSING_APPLE_TOUCH_ICON
infoDocumentedEvery page
The page links no apple-touch-icon and /apple-touch-icon.png is not served
Fix: Add
Source: developer.apple.com(opens in a new tab)<link rel="apple-touch-icon" href="/apple-touch-icon.png">with a 180×180 PNG; iOS shows it when the site is added to the home screen.
Performance
18 checks · 2 groups
Core Web Vitals measured in a real browser, page weight, requests, and images.
Speed and Core Web Vitals
11 checksLab timings, layout shifts, and the weight of what each page loads.
SLOW_LCP
criticalDocumentedEvery page
Synthetic lab Largest Contentful Paint is 3000ms (threshold: 2500ms)
Fix: Find the LCP element in the evidence. If it is an image, don't lazy-load it, give it
Source: web.dev(opens in a new tab)fetchpriority="high", and serve it at its displayed size; if it is text, remove render-blocking resources ahead of it.SLOW_TTFB
warningDocumentedEvery page
Synthetic lab Time to First Byte is 1000ms (threshold: 800ms)
Fix: Cache the HTML at the edge or in the app, remove slow work before the first byte (database calls, server-side API waterfalls), and check the server region against your visitors.
Source: web.dev(opens in a new tab)HIGH_CLS
warningDocumentedEvery page
Synthetic lab Cumulative Layout Shift is 0.200 (good: at most 0.1)
Fix: Give images, videos, iframes, and ad slots explicit
Source: web.dev(opens in a new tab)widthandheight(oraspect-ratio), and don't insert content above existing content after load.HIGH_TBT
warningDocumentedEvery page
Synthetic lab Total Blocking Time is 300ms (threshold: 200ms)
Fix: Split long JavaScript tasks, defer or remove unused scripts, and move heavy work off the main thread or after interaction.
Source: web.dev(opens in a new tab)LARGE_JS
warningHeuristicEvery page
Synthetic lab JavaScript transfer total is 2.0MB (threshold: 1MB)
Fix: Code-split by route, remove unused dependencies, and load third-party scripts only where they are needed.
Source: web.dev(opens in a new tab)TOO_MANY_THIRD_PARTY_REQUESTS
warningHeuristicEvery page
Synthetic lab load observed 20 third-party requests (threshold: 10)
Fix: Audit third-party tags, remove unused ones, and load the rest after the main content (for example through a tag manager trigger on interaction).
Source: web.dev(opens in a new tab)SLOW_FCP
infoDocumentedEvery page
Synthetic lab First Contentful Paint is 2000ms (threshold: 1800ms)
Fix: Inline critical CSS, defer non-critical scripts with
Source: web.dev(opens in a new tab)deferorasync, and preload the main web font withfont-display: swap.SLOW_LOAD
infoHeuristicEvery page
Synthetic lab page load time is 4000ms (threshold: 3000ms)
Fix: Defer resources that aren't needed for the first view: third-party tags, below-the-fold images (
Source: developer.mozilla.org(opens in a new tab)loading="lazy"), and non-critical scripts.RENDER_BLOCKING_RESOURCES
infoHeuristicEvery page
5 render-blocking resource(s) observed in the synthetic lab load
Fix: Add
Source: developer.chrome.com(opens in a new tab)deferto scripts in the head, inline the CSS needed for the first view, and load the rest withmediaor after load.LARGE_PAGE
infoHeuristicEvery page
Synthetic lab transfer total is 4.0MB (threshold: 3MB)
Fix: Compress and resize images, serve AVIF or WebP, remove unused JavaScript and CSS, and enable Brotli or gzip.
Source: developer.chrome.com(opens in a new tab)TOO_MANY_REQUESTS
infoHeuristicEvery page
Synthetic lab load observed 100 resource requests (threshold: 80)
Fix: Bundle small scripts and styles, inline tiny icons as SVG, and remove tags and widgets the page doesn't need.
Source: developer.chrome.com(opens in a new tab)
Images
9 checksImage sizes, formats, loading, and alternative text.
LAZY_LCP_IMAGE
warningDocumentedEvery page
The largest paint is a lazy-loaded image (img.hero, hero.webp), so it starts loading late
Fix: Remove
Source: web.dev(opens in a new tab)loading="lazy"from the image that is the largest paint; lazy-load only images below the first screen.IMAGES_WITHOUT_ALT
warningDocumentedEvery page
3 image(s) have no alt attribute
Fix: Add
Source: w3.org(opens in a new tab)alttext describing each informative image; usealt=""for decorative images so screen readers skip them.OVERSIZED_IMAGES
infoHeuristicEvery page
1 image(s) are much larger than displayed at this viewport's 1.00x pixel ratio: hero.jpg (3000px wide, shown at 300px)
Fix: Serve each image near its displayed size times the device pixel ratio, with
Source: developer.chrome.com(opens in a new tab)srcsetandsizesso the browser picks the right file.IMAGES_WITHOUT_DIMENSIONS
infoDocumentedEvery page
1 image(s) have no width and height or aspect ratio: photo.webp
Fix: Add
Source: web.dev(opens in a new tab)widthandheightattributes (or a CSSaspect-ratio) to every image so the browser reserves its space before it loads.LCP_IMAGE_NOT_PRIORITIZED
infoDocumentedEvery page
The largest paint is an image (img.hero, hero.webp) without fetchpriority="high" or a preload
Fix: Add
Source: web.dev(opens in a new tab)fetchpriority="high"to the LCP image, or<link rel="preload" as="image" href="…">when it is a CSS background.LEGACY_IMAGE_FORMAT
infoHeuristicEvery page
1 large image(s) use an older format; WebP would save about 25 KB: photo.jpg (image/jpeg, 400 KB)
Fix: Serve large photos as AVIF or WebP, with
Source: developer.chrome.com(opens in a new tab)<picture>fallbacks if you support old browsers.RESPONSIVE_IMAGE_TOO_LARGE
infoDocumentedEvery page
1 image(s) download a srcset file far larger than their slot; the right candidates would save about 282 KB: hero-1600.webp picks the 1600w file for a 100px slot where the 400w file would do (no sizes attribut…
Fix: Give the image a
Source: developer.mozilla.org(opens in a new tab)sizesattribute that matches its real slot, such assizes="(max-width: 600px) 100vw, 300px"; without it the browser assumes the image fills the viewport.OFFSCREEN_IMAGES_NOT_LAZY
infoDocumentedEvery page
1 image(s) below the first screen load immediately; loading="lazy" would defer about 80 KB: gallery.webp (2400px down, 80 KB)
Fix: Add
Source: web.dev(opens in a new tab)loading="lazy"to images below the first screen, and keep it off the hero image and anything visible on load.POOR_ALT_TEXT
infoHeuristicEvery page
1 image(s) have alt text that doesn't describe them: "IMG_2041.jpg"
Fix: Describe what the image shows or does, instead of a file name or a word like "image"; use
Source: w3.org(opens in a new tab)alt=""for decorative images.
Accessibility
7 checks · 2 groups
Color contrast, document language, headings, form labels, and alt text.
Color contrast
1 checkText that is too faint against its background to read comfortably.
LOW_TEXT_CONTRAST
warningDocumentedEvery page
3 text element(s) are below the WCAG contrast minimum: "Free shipping on orders over $50" #999999 on #ffffff (2.84:1, needs 4.5:1)
Fix: Darken the text or lighten its background until the ratio reaches 4.5:1, or 3:1 for text of at least 24px (18.66px bold); the evidence lists each color pair and its ratio.
Source: w3.org(opens in a new tab)
Structure and forms
4 checksHeadings, page language, and labels that assistive technology relies on.
MISSING_LANG
warningDocumentedEvery page
HTML element has no lang attribute
Fix: Set the page language on the root element, for example
Source: w3.org(opens in a new tab)<html lang="en">.INPUTS_WITHOUT_LABELS
warningDocumentedEvery page
2 input(s) missing associated labels
Fix: Associate each control with a
Source: w3.org(opens in a new tab)<label for="…">, wrap it in a label, or give itaria-label.MISSING_H1
infoHeuristicEvery page
Page has no H1 heading
Fix: Add one
Source: dequeuniversity.com(opens in a new tab)<h1>naming the page's main content, or give the existing top heading an accessible name.HEADING_LEVEL_SKIP
infoHeuristicEvery page
Heading outline skips one or more levels
Fix: Use the next heading level down (H2 after H1, H3 after H2); style headings with CSS instead of choosing levels for their size.
Source: dequeuniversity.com(opens in a new tab)
Content
5 checks · 1 group
Thin, placeholder, duplicate, and near-duplicate content across the site.
Content
6 checksPlaceholder text, duplicated content, and pages that differ from their siblings.
PLACEHOLDER_CONTENT
warningHeuristicEvery page
Page shows placeholder text: default title "React App", "lorem ipsum" filler text
Fix: Replace the placeholder with real copy, and check the template or data source that produced it; a framework's default title usually means the head was never set.
Source: developers.google.com(opens in a new tab)NEAR_DUPLICATE_CONTENT
warningHeuristicAcross the site
Fix: Merge the near-identical pages, or point the copies at the preferred one with
Source: developers.google.com(opens in a new tab)rel="canonical"; if they should differ, add the content that makes each one distinct.THIN_CONTENT
infoHeuristicEvery pageHidden by default
Page has only 10 words (recommended: ≥300)
Fix: Only expand the page if visitors need more information to complete their task; word count itself is not a ranking factor.
Source: developers.google.com(opens in a new tab)MULTIPLE_H1
infoHeuristicEvery pageHidden by default
Page has 2 H1 headings; target is one
Fix: Optional: keep one H1 for the page's main topic if it helps the outline; search engines accept several.
Source: searchenginejournal.com(opens in a new tab)DUPLICATE_H1
infoHeuristicAcross the site
Fix: Make each page's H1 name its own subject rather than a section label shared by every page.
Source: developers.google.com(opens in a new tab)CONTENT_OUTLIER
infoHeuristicAcross the site
Fix: Check whether these pages are missing content their siblings have, such as a description that failed to load or an empty product.
Source: developers.google.com(opens in a new tab)
Security
4 checks · 1 group
Security headers and mixed content on pages served over HTTPS.
Security headers
4 checksResponse headers and HTTPS hygiene that protect visitors.
MIXED_CONTENT
warningDocumentedEvery page
HTTPS page loads 1 resource(s) over HTTP: http://cdn.example.com/app.js
Fix: Load every subresource over
Source: developer.mozilla.org(opens in a new tab)https://; browsers block insecure scripts and frames and warn about insecure images.MISSING_CSP
infoDocumentedEvery page
Response has no Content-Security-Policy header
Fix: Add a
Source: developer.mozilla.org(opens in a new tab)Content-Security-Policyheader, starting with a report-only policy to find what the page loads.MISSING_NOSNIFF
infoDocumentedEvery page
Response has no X-Content-Type-Options header
Fix: Send
Source: developer.mozilla.org(opens in a new tab)X-Content-Type-Options: nosniffon every response.MISSING_HSTS
infoDocumentedEvery page
HTTPS response has no Strict-Transport-Security header
Fix: Send
Source: developer.mozilla.org(opens in a new tab)Strict-Transport-Security: max-age=31536000; includeSubDomainson HTTPS responses once every subdomain serves HTTPS.
How a scan works
A real browser
Pages render in headless Chromium at a mobile profile, the way Google indexes them. Arachne compares the raw HTML with the rendered page.
Site probes
Each crawl also requests a page that should not exist, the http:// and www variants of the site, and robots.txt rules for search and AI crawlers.
Every scan, compared
Each finding has a fingerprint. A new scan is matched with the previous one, so you see what was fixed, what is new, and what is still open.
Blocked, not guessed
When bot protection answers with a challenge page, Arachne reports the page as blocked instead of analyzing the challenge.