Every Webflow fix we catalog

SEOLZ catalogs 167 fixes for Webflow across 6 areas — SEO, answer-engine readiness, accessibility, security and site-health. Each lists the exact steps for Webflow, with a link to the official docs.

SEO · 45 fixes

Catalog coverageModerate effort

Ensure every product and category page is crawlable and discoverable by submitting a complete XML sitemap, fixing internal links, and removing any crawl blocks so Google can index your full catalog.

On Webflow

  1. Sitemap: In Webflow Designer → Project Settings → SEO tab → enable 'Auto-generate sitemap'. Publish the site and submit the sitemap URL (/sitemap.xml) to Google Search Console.
  2. Noindex on Collection pages: In the Designer, open your Products Collection page template → Page Settings (gear icon) → SEO tab → ensure 'Exclude this page from search results' is NOT checked. Do the same for Category collection templates.
  3. robots.txt: Project Settings → SEO → edit the robots.txt field. Ensure there are no Disallow rules blocking your /products or /shop paths.
  4. Internal linking: In the Designer, open your Navbar component and add Collection List links pointing to your Products and Categories collections. Ensure the CMS Collection pages are linked from the main navigation.
  5. CMS items published: In the Webflow CMS (Editor or Designer → CMS), ensure all Product and Category items are set to 'Published' — unpublished CMS items are excluded from the sitemap and site.
Cwv clsModerate effort

Eliminate unexpected layout shifts by reserving explicit space for every image, video, embed, ad, and late-loading widget before it loads, so nothing on your page jumps around as it renders.

On Webflow

  1. Images: In the Webflow Designer, click any Image element > Settings panel (gear icon). Set an explicit Width and Height, or use the Style panel to add an aspect-ratio property (e.g. aspect-ratio: 4/3) to the image's wrapper div. This ensures the browser reserves the right space.
  2. CMS images: For CMS Collection images (e.g. product photos), select the image in the Collection List and in the Style panel set the image wrapper to a fixed aspect-ratio or percentage-based height. Do not leave image wrappers at height: auto without a defined aspect ratio.
  3. Fonts: Go to Project Settings > Fonts. Webflow loads Google Fonts and Adobe Fonts automatically with font-display: swap for Google Fonts. For custom uploaded fonts, go to Project Settings > Fonts > Upload Font and ensure font-display is set (add custom CSS in the global stylesheet: @font-face { font-display: swap; }).
  4. Announcement bars and sticky headers: Build announcement bars as a fixed-height Section at the top. Set an explicit min-height in the Style panel so the space is always reserved, even before any CMS content or dynamic text loads.
  5. Third-party embeds and scripts: Add non-critical third-party scripts (chat, analytics, reviews) via Project Settings > Custom Code > Footer Code section, not the Head section, so they load after the main content is painted.
  6. Interactions/animations: In the Webflow Interactions panel, avoid 'Move' or 'Size' entrance animations on above-the-fold elements that trigger on page load — these count as layout shifts. Use opacity-only animations for reveal effects instead.
Cwv lcpModerate effort

Reduce Largest Contentful Paint (LCP) to under 2.5 seconds by serving your hero image in a modern format, preloading it, and eliminating render-blocking resources.

On Webflow

  1. In the Webflow Designer, select your hero image element → in the Settings panel (right sidebar, gear icon) → upload a WebP version of the image, or use the Asset Manager (left panel → Assets) to replace the existing image with a WebP file.
  2. Set 'Loading' to 'Eager' (not Lazy) for the hero image: in the Image Settings panel → Loading dropdown → select 'Eager'. Also set 'Preload' to 'High Priority' if available in your Webflow plan.
  3. Add a preload link via Project Settings → Custom Code → Head Code: <link rel='preload' as='image' href='YOUR-WEBP-CDN-URL' fetchpriority='high'>. Get the CDN URL from the published page's source or the Assets panel.
  4. Defer non-critical JS: in Project Settings → Custom Code, ensure third-party <script> tags in the Head have 'defer' added. Move non-critical scripts to the Footer Code field instead.
  5. Review and remove unused Webflow interactions/animations on the hero section — heavy GSAP or Lottie animations above the fold significantly delay LCP. Delete or move them below the fold.
  6. Publish and verify with PageSpeed Insights (mobile). Webflow's CDN (via Fastly) handles global delivery; the main wins are format, preload, and removing blocking resources.
Duplicate meta descriptionModerate effort

Write a unique, page-specific meta description for every page on your store so Google can display a relevant snippet in search results.

On Webflow

  1. For static pages: Webflow Designer → left panel → Pages (book icon) → hover over the page → Settings gear → SEO Settings section → 'Meta Description' field → publish.
  2. For CMS Collection pages (e.g. Products, Blog Posts): Designer → CMS → open the Collection → click into an individual item → find the 'SEO Settings' section → fill in the 'Meta Description' field, OR use a dynamic bind: in the Collection Template page settings, bind the Meta Description field to a CMS field (e.g. a 'SEO Description' plain-text field you create in the collection schema) so each item auto-populates a unique description.
  3. To add a dedicated SEO description field: CMS → Collections → edit the collection schema → Add Field → Plain Text → name it 'SEO Description' → then bind it in the template page's SEO settings.
  4. Bulk-fill CMS content: export the collection as CSV (CMS → Collections → Export), fill the SEO Description column in a spreadsheet, then re-import.
Duplicate titleModerate effort

Write a unique, descriptive title tag for every page on your store so no two pages share the same title.

On Webflow

  1. Open the Webflow Designer.
  2. For static pages: select the page in the Pages panel (left sidebar), click the Settings icon (gear) next to the page name, and update the 'Title Tag' field under the 'SEO Settings' section.
  3. For CMS collection pages (e.g. products, blog posts): open the Collection in the CMS panel → go to Collection Settings → find the 'Title Tag' field and use a dynamic field binding (e.g. bind to the 'Name' field plus a static suffix like ' | My Store') so every item generates a unique title automatically.
  4. For the site-wide default fallback: Project Settings → SEO → 'Default Meta Title' — this only applies when no page-level title is set, so ensure every template has its own binding.
  5. Publish the site after making changes, then verify in a browser tab or with Google Search Console's URL Inspection tool.
Faceted url indexableModerate effort

Point every faceted/filter URL's canonical tag to the clean, unfiltered category URL (or add noindex) so Google treats filtered pages as one authoritative page instead of thousands of duplicates.

On Webflow

  1. In Webflow, canonical tags are managed per-page in the Page Settings. For CMS Collection pages (the equivalent of category/filter pages), open the Designer, click on the Collection page template, and go to Page Settings (gear icon) → SEO Settings.
  2. In the 'Canonical URL' field, enter the clean base collection URL (e.g., `https://www.example.com/products`) rather than leaving it dynamic or self-referencing with parameters.
  3. For filter functionality built with Webflow Filters (native) or Finsweet's CMS Filter: Finsweet's CMS Filter uses URL parameters by default — go to your page's custom code (`<head>` tag) and add a script that sets the canonical to the base URL and optionally injects noindex when filter params are present.
  4. Add this to the `<head>` custom code of your collection page: `<script>if(window.location.search){document.querySelector('link[rel=canonical]').href=window.location.pathname.split('?')[0];}</script>` — this strips query strings from the canonical at runtime.
  5. Publish your site after making changes and verify with a URL inspection tool that the canonical resolves to the clean URL.
  6. Webflow's auto-generated sitemap excludes query-string URLs by default — confirm this in your published sitemap.xml.
Images missing altModerate effort

Add descriptive alt text to every image on your store so search engines can understand them and all shoppers can access your content.

On Webflow

  1. In the Webflow Designer, click any image element on the canvas to select it.
  2. In the right-hand Element Settings panel (the gear icon tab), find the 'Alt Text' field and type your description.
  3. To mark a decorative image as decorative (empty alt), check the 'Decorative (no alt text needed)' checkbox — Webflow will output alt="" automatically.
  4. FOR CMS COLLECTION IMAGES: Open the CMS Collection schema (CMS > Collections > [your collection] > Settings), ensure there is an 'Image' field. In the Designer, bind the alt text field to a separate CMS text field (e.g., 'Product Image Alt') by clicking the alt text binding icon next to the Alt Text input.
  5. FOR ECOMMERCE PRODUCT IMAGES (Webflow Commerce): Go to Ecommerce > Products, open a product, scroll to each product image, and fill in the alt text field directly in the product editor.
Low performance scoreLarger project

Improve your Lighthouse/PageSpeed performance score by reducing page weight, deferring JavaScript, optimizing images, and fixing Core Web Vitals metrics so your store loads fast on mobile and desktop.

On Webflow

  1. Images — In the Designer, select each image → Element Settings panel: enable 'Lazy load' for below-fold images; set explicit width and height. Use the Webflow Asset Manager to upload WebP images directly.
  2. Interactions & animations — Webflow Interactions add significant JS. In the Interactions panel, audit and delete any unused animations. Disable interactions that fire on every page scroll if not essential.
  3. Custom code — Project Settings → Custom Code (site-wide) and Page Settings → Custom Code (per-page): audit all <head> and before-</body> scripts. Move analytics and marketing scripts to the footer and add defer or async attributes.
  4. Fonts — Project Settings → Fonts: remove any unused Google Fonts or Adobe Fonts. Each font family/weight is a separate network request.
  5. Unused CSS — Webflow does not generate unused CSS the way hand-coded sites do, but third-party embed scripts can. Audit embed blocks on each page.
  6. Hosting CDN — Webflow's hosting uses Fastly CDN automatically. Ensure your site is published to Webflow Hosting (not a custom server export without CDN) to benefit from edge caching.
Meta description too longQuick win

Shorten your meta description to 150–160 characters so Google displays your full message in search results instead of cutting it off with "…".

On Webflow

  1. Open your Webflow Designer. Click on the page you want to edit in the Pages panel (left sidebar).
  2. Click the Settings (gear) icon next to the page name → go to the 'SEO Settings' section.
  3. Edit the 'Meta Description' field. Webflow shows a live SERP preview; aim to keep the description text from being truncated in the preview.
  4. For CMS Collection pages (e.g. products or blog posts): go to the CMS Collections panel → open the Collection → open the Collection Settings → edit the Meta Description field, which can include dynamic field bindings (e.g. {{description}} pulled from a CMS field). Ensure the bound field's content is kept under 160 characters.
  5. Click 'Save' and then 'Publish' the site.
Meta description too shortModerate effort

Expand every meta description to 120–160 characters so Google shows your custom summary in search results instead of auto-generating one.

On Webflow

  1. For a static page: open the Designer → select the page from the Pages panel → click the gear icon next to the page name → 'SEO Settings' section → edit the 'Meta Description' field (character counter shown) → Save.
  2. For CMS collection items (e.g. products or blog posts): go to the CMS Collection settings (Designer → CMS → Collection) → open a collection item → fill in the 'Meta Description' field directly, or set up a dynamic binding by connecting the field to a CMS text field so descriptions are auto-populated from your product data.
  3. For the homepage: Pages panel → Home → gear icon → SEO Settings → Meta Description → Save.
  4. Publish the site after all changes: Publish button (top right) → Publish to your domain.
Missing canonicalModerate effort

Add a self-referencing canonical tag to every page so Google knows which URL is the "official" version of that content.

On Webflow

  1. Webflow automatically outputs self-referencing canonical tags for all published pages on paid hosting plans.
  2. To set a custom canonical URL on any specific page: open the page in the Designer → click the Settings icon (gear) for that page → scroll to the 'SEO Settings' section → enter your preferred URL in the 'Canonical URL' field.
  3. For CMS Collection pages (e.g. product detail pages), open the Collection in the CMS → click the Collection page template in the Designer → Page Settings → SEO Settings → set the canonical using a dynamic field binding if needed.
  4. After publishing, use View Page Source to verify the canonical tag appears in `<head>` with the correct URL.
Missing h1Quick win

Add a single, descriptive H1 heading to every page that currently lacks one, so search engines and shoppers immediately understand what the page is about.

On Webflow

  1. Open the Webflow Designer for the project and navigate to the page missing an H1.
  2. In the left-hand Navigator panel, check whether an 'H1' element exists on the page canvas.
  3. If missing, drag an **H1** element from the Add panel (Elements → Typography → Heading → set Tag to H1) onto the canvas as the first content element.
  4. If a large text element exists but is set to a `<div>` or `<h2>`, click it → in the right-hand Element Settings panel → change the Tag dropdown to **H1**.
  5. For **Webflow Ecommerce product pages**, open the Product Template page → ensure the Product Name text element's tag is set to H1 in Element Settings.
  6. Publish the site and verify using the browser's Inspect tool or a headings extension to confirm exactly one `<h1>` per page.
Missing meta descriptionQuick win

Write a unique meta description of 120–160 characters for every page so Google has compelling snippet text to show in search results.

On Webflow

  1. For a static page: in the Webflow Designer, open Page Settings (click the Pages icon in the left panel → hover over the page → click the settings gear) → scroll to 'SEO Settings' → fill in the 'Meta Description' field (160-char counter shown) → Save & Publish.
  2. For CMS collection items (products, blog posts): go to the CMS Collection settings → add or edit a plain-text field named 'Meta Description' → in the collection template page's Page Settings, bind the Meta Description field to that CMS field via the '+' dynamic bind button → Publish.
  3. For the homepage: Pages panel → Home page settings gear → SEO Settings → fill Meta Description → Save & Publish.
  4. Verify in the published site by right-clicking the page → View Source and searching for 'meta name="description"'.
Missing og descriptionQuick win

Add an og:description meta tag to every page so social platforms display a compelling preview when your store's links are shared.

On Webflow

  1. In the Webflow Designer, click the Pages panel (page icon, top-left) → hover over the page → click the Settings gear icon.
  2. In the 'SEO Settings' section, fill in the 'Meta Description' field. Webflow automatically outputs this as og:description.
  3. For the dedicated Open Graph description (if you want it to differ): scroll down to the 'Open Graph Settings' section in the same page settings panel → fill in the 'Open Graph Description' field.
  4. For CMS collection items (e.g. products or blog posts): open the Collection Settings → add or bind a plain-text field (e.g. 'SEO Description') → in the Collection Page template, open Page Settings → bind the 'Meta Description' and 'Open Graph Description' to that CMS field.
  5. Publish the site, then validate with Facebook Sharing Debugger.
Missing og imageModerate effort

Add an og:image meta tag to every page so social media platforms and messaging apps display a rich preview image when someone shares your store's link.

On Webflow

  1. In the Webflow Designer, open the Pages panel (left sidebar) → hover over the page → click the Settings gear icon.
  2. Scroll to the 'Open Graph Settings' section → click the OG Image field → upload or select a 1200×630 px image from your Assets panel. This sets the og:image for that static page.
  3. For CMS Collection pages (e.g., products, blog posts): open the Collection settings in the CMS panel → go to the Collection page template in the Designer → open Page Settings → in the OG Image field, bind it to a CMS image field (e.g., 'Main Image' or 'Featured Image') so every item automatically uses its own image.
  4. For a site-wide fallback, set the OG image on your homepage and key landing pages individually, as Webflow does not have a single global OG fallback outside of per-page settings.
  5. Publish the site and validate with the Meta Sharing Debugger.
Missing og titleQuick win

Add an og:title meta tag to every page so your store looks great when shared on Facebook, Pinterest, LinkedIn, and other social platforms.

On Webflow

  1. In the Webflow Designer, open the Pages panel (left sidebar) and click the gear icon next to the page you want to fix.
  2. In the Page Settings panel that appears, scroll to the 'SEO Settings' section. The 'Title Tag' field populates the page <title> and is also used by Webflow as the og:title by default in many templates.
  3. To set a dedicated og:title, scroll further in Page Settings to the 'Open Graph Settings' section → fill in the 'Open Graph Title' field. This outputs a separate og:title tag.
  4. For CMS-powered pages (e.g. Products, Blog Posts): open the CMS Collection settings → go to the Collection's page template in the Designer → in the page gear settings, bind the 'Open Graph Title' field to the CMS item's Name or Title field using the dynamic data binding (purple field selector).
  5. Publish your site, then validate with the Facebook Sharing Debugger.
Missing titleQuick win

Add a unique, descriptive title tag (30–60 characters) to every page that is missing one.

On Webflow

  1. In the Webflow Designer, select the page from the Pages panel (left sidebar).
  2. Click the settings (gear) icon next to the page name → go to the 'SEO Settings' section.
  3. Fill in the 'Title Tag' field with your descriptive title (30–60 characters).
  4. For CMS collection items (e.g. products): open the CMS Collection settings → add or edit the 'SEO Title' field and bind it to the relevant CMS field using the '+' dynamic bind button so every item gets a unique title automatically.
  5. Publish the site for changes to take effect.
Multiple h1Moderate effort

Reduce every page to exactly one H1 tag that clearly describes the page's main topic, removing or converting all extra H1s to lower-level headings (H2, H3, etc.).

On Webflow

  1. Open the Webflow Designer for your project and navigate to the affected page.
  2. In the Navigator panel (left sidebar), look for all elements with the tag 'H1'. You can also use Edit → Find (Ctrl/Cmd+F) and filter by element type.
  3. Click each H1 element that is NOT the primary page title. In the element settings panel on the right, change the HTML tag from 'H1' to 'H2', 'H3', or the appropriate level.
  4. Check CMS Collection page templates (e.g., Blog Post Template, Product Template) in the same way — a single template fix will apply to all generated pages.
  5. Also inspect your Navbar or Header Symbol/Component — if the site name or any nav label is set to H1, change it to a <p> or <span> tag.
  6. Publish the site, then open a live page and run the 'Headings Map' browser extension or DevTools to confirm one H1 per page.
Noindex detectedQuick win

Remove or replace the `noindex` directive on any page you want Google to find and rank, then verify the change with Google Search Console.

On Webflow

  1. For individual CMS items or static pages: open the Designer → Pages panel → click the settings gear beside the page → SEO settings section → uncheck 'Exclude from search index (noindex)' if it is checked.
  2. For CMS collection items (products, blog posts): Designer → CMS Collections → open the Collection Settings → check if 'Exclude from search index' is toggled on for the collection, and toggle it off.
  3. For site-wide settings: Webflow Dashboard → Project Settings → SEO tab → confirm no global noindex is enabled.
  4. After changing, publish the site to push the updated meta tags live, then verify by viewing the page source for the `<meta name="robots">` tag.
Non self canonicalModerate effort

Ensure every page's canonical tag points to that same page's own URL — fix any canonical that currently points to a different page unless the redirect is genuinely intentional.

On Webflow

  1. In the Webflow Designer, open the Pages panel and click the Settings gear for the affected page.
  2. Scroll to the 'SEO Settings' section — Webflow does not expose a canonical field directly in the UI for standard pages; it auto-generates self-referencing canonicals.
  3. If a non-self canonical exists, check the Custom Code tab for the page (or the site-wide <head> code under Project Settings → Custom Code → Head Code) for a manually added <link rel="canonical"> tag.
  4. Remove or correct the hard-coded canonical so Webflow's automatic canonical (which equals the page's own slug/URL) takes over.
  5. For CMS Collection pages, check the Collection Template page's Custom Code section as well.
  6. Publish your changes and verify with View Source.
Page speed warningModerate effort

Reduce your page load time to under 1.5 seconds by compressing images, eliminating render-blocking resources, and enabling caching so Google and shoppers experience a fast site.

On Webflow

  1. Images: In the Asset Manager (the image icon in the left panel), upload images in WebP format at the exact maximum display size. In each Image element's settings, enable 'Lazy load' for below-the-fold images.
  2. Scripts: In Project Settings → Custom Code, audit 'Head Code' and 'Footer Code'. Move all non-critical scripts to the Footer section and add 'defer' or 'async' attributes manually in the <script> tag.
  3. Interactions/animations: In the Interactions panel, audit all scroll and load animations. Remove or simplify heavy animations, particularly on mobile breakpoints.
  4. Fonts: In Project Settings → Fonts, remove any unused Google Fonts or custom fonts — each unused font file adds unnecessary load.
  5. CDN: Webflow hosts all sites on AWS CloudFront CDN automatically — ensure you are using Webflow-hosted asset URLs (not external hotlinked files) to benefit.
  6. Verify: In Project Settings → SEO, use the 'Analyze' button or run Google PageSpeed Insights on your published Webflow domain after publishing changes.
Search results indexableModerate effort

Add a noindex robots meta tag to all internal search results pages and block the search path in robots.txt to prevent thin, duplicate, near-infinite pages from polluting Google's index.

On Webflow

  1. In the Webflow Designer, select your Search Results page in the Pages panel on the left.
  2. Click the gear icon to open Page Settings, then scroll to 'SEO Settings'.
  3. Check the box 'Exclude this page from search results (noindex)' — Webflow will add the meta tag automatically.
  4. For robots.txt: go to Project Settings → SEO → Robots.txt and add: Disallow: /search (or whatever slug your search page uses).
  5. Publish the site and confirm by viewing the page source of a live search URL.
Seo category description missingQuick win

Write a unique 100–200 word description for every product category page explaining what it contains and who it's for.

On Webflow

  1. Open Webflow Designer and navigate to your CMS Collection for product categories (e.g. 'Categories' collection).
  2. In the CMS Collection settings, add a new field: type 'Rich Text' or 'Plain Text', and name it 'Category Description'.
  3. In the Collection List (your category template page), add a Rich Text or Text element and bind it to the new 'Category Description' field.
  4. Open the CMS Editor or Webflow Editor, select each category item, and fill in the description (100–200 words).
  5. For SEO meta description, in the category Collection template page settings, bind the SEO Description field to your 'Category Description' field (or a dedicated 'Meta Description' field).
  6. Publish your site.
Seo category description thinModerate effort

Expand your category page description to at least 150–300 words of genuinely useful, keyword-rich content that explains what shoppers will find in the category.

On Webflow

  1. In the Webflow Designer, open the CMS Collections panel and select your Product Category collection.
  2. Add or locate a rich-text or plain-text field named 'Description' (or similar) in the collection schema.
  3. Go to the CMS → Product Categories content tab and click into the specific category item; fill in the Description field with your expanded text.
  4. In the Designer, open the Category Template page, and bind a Rich Text element or Text element to the Description field so it renders on the live page.
  5. Publish the site.
Seo category emptyQuick win

Either populate the empty category with relevant products, or apply a noindex tag and remove it from navigation so Google does not waste crawl budget on a page with no content.

On Webflow

  1. To ADD products: Webflow Designer → CMS → your product Collection → add items and assign them the empty category, OR open the Category collection item and verify that product items reference it via the multi-reference or category field.
  2. To NOINDEX: CMS → Categories Collection → open the empty category item → scroll to 'SEO Settings' field (if added to your Collection schema) → set noindex, OR in Designer open the Category template page → Page Settings (gear icon) → SEO → enable 'Exclude from search index' → Publish. For conditional noindex based on product count, a custom Attribute <meta name='robots' content='noindex'> can be added in the page's custom <head> code using a conditional visibility workaround.
  3. To HIDE from nav: In the Designer, find your navigation component → locate the dynamic list or static link rendering the empty category → add a conditional visibility rule so items with zero products are hidden, then Publish.
  4. To DELETE and REDIRECT: CMS → Categories → delete the item. Then go to Project Settings → Hosting → 301 Redirects → add old category slug → target URL → Save and Publish.
Seo category sparseModerate effort

Add more products to the category or consolidate it with a closely related one so Google sees a substantive, valuable page worth ranking.

On Webflow

  1. In the Webflow Designer, open your Ecommerce → Categories collection. Identify the sparse category item.
  2. To add products: open each relevant product in Ecommerce → Products, find the 'Category' reference field, and assign it to the correct category.
  3. To add a category description: edit the sparse category item in the CMS and populate the description field; make sure your category template page binds this field to a visible text element.
  4. To merge/redirect: reassign all products, then set up a 301 redirect in Project Settings → SEO → Redirects — add the old category slug mapping to the new category slug.
  5. Delete the old category CMS item once all products are moved and the redirect is in place.
  6. Publish the site, then verify the redirect in Google Search Console URL Inspection and request indexing of the target URL.
Seo facet url not canonicalizedModerate effort

Add a canonical tag pointing filtered and sorted category URLs back to the clean (unfiltered) category page URL to prevent duplicate content and crawl waste.

On Webflow

  1. Webflow Commerce does not generate classic faceted navigation filter URLs out of the box, so this is most relevant if you have implemented custom filtering via query parameters using JavaScript.
  2. For Collection pages with query-parameter-based filters: open your Webflow project → go to the Collection page template in the Designer → open Page Settings (gear icon) → SEO tab. Webflow outputs a self-referencing canonical automatically for Collection pages.
  3. To canonicalize filtered variants (URLs with `?` query parameters) back to the clean Collection page, add a Custom Code snippet in the Page Settings → Custom Code → `<head>` section: `<script>if(window.location.search){var l=document.createElement('link');l.rel='canonical';l.href=window.location.origin+window.location.pathname;document.head.appendChild(l);}</script>`
  4. Publish the site and verify by inspecting the page source on a filtered URL.
Seo product description minimalModerate effort

Expand thin product descriptions to at least 300 words by adding specifications, use cases, and benefits so Google has enough content to rank and shoppers have enough information to buy.

On Webflow

  1. In the Webflow Designer, open the CMS and go to your Products collection.
  2. Click the product to open its CMS item editor.
  3. Locate the 'Description' rich-text field and click 'Edit' to open the rich-text editor. Add structured paragraphs, bulleted lists, and bold headings for specs and use cases.
  4. For an FAQ, add a new Multi-reference or Long Text CMS field called 'FAQ' in the Collection Settings, then bind it to a collapsible component on your product template page.
  5. Alternatively, add extra Long Text fields (e.g. 'Specifications', 'Use Cases') to the Products collection schema and display them in dedicated sections on the product template.
  6. Publish your changes.
Seo product description missingModerate effort

Write and publish a 200–400 word product description covering what the product is, its key specs, who it's for, and how to use it.

On Webflow

  1. Open your Webflow project and go to the CMS panel → Products collection.
  2. Click on the product item that needs a description.
  3. Find the Description rich-text field (default Webflow Ecommerce field) and click into it.
  4. Write your 200–400 word description. Apply heading, bold, and list formatting using the inline toolbar.
  5. Publish your site. To surface the description in structured data, bind the Description field to a JSON-LD embed block in your Product template page using Webflow's dynamic field bindings.
Seo product description thinModerate effort

Expand thin product descriptions to at least 300 words of unique, keyword-rich content that answers real shopper questions and gives Google enough text to understand what you sell.

On Webflow

  1. Open the Webflow Designer → go to the CMS (Content Manager) → select your Products collection.
  2. Click the product item you want to update to open the CMS item editor.
  3. Find the 'Description' (or equivalent Rich Text) field and click 'Edit' to open the rich-text editor.
  4. Write or paste your expanded content. Use Heading, Paragraph, and List blocks inside the rich-text editor for structure.
  5. Click 'Save' and publish the site. Webflow renders CMS rich-text content as static HTML in the published output — fully crawlable.
  6. If your product template uses a separate 'Short Description' plain-text field for the above-the-fold summary, put the full expanded content in the Rich Text field and bind both to your product template page.
Seo product image alt filenameModerate effort

Replace filename-based alt text on product images with short, descriptive phrases that accurately describe each image's content.

On Webflow

  1. Open your project in the Webflow Designer.
  2. Click the product image element on the canvas to select it.
  3. In the Element Settings panel on the right (the gear icon), find the 'Alt text' field.
  4. Replace the filename-based value with your descriptive alt text.
  5. For Webflow Ecommerce products: go to the CMS → Products collection → open a product item → find the image field → click 'Edit' on the image → update the 'Alt text' field.
  6. Publish your site after making changes.
Seo product missing brandQuick win

Add a `brand` property to your Product structured data (schema.org/Product) so search engines can match your listings to brand-specific queries.

On Webflow

  1. In the Webflow Designer, open your Product Template page (CMS → Collections → Products → open the template).
  2. Add a Custom Field called 'Brand' (type: Plain Text) to your Products CMS collection via CMS → Collections → Products → Add Field.
  3. Fill in the Brand value for each product in the CMS.
  4. On the Product Template page, add an Embed element (HTML Embed widget). Paste a JSON-LD Product script and bind the brand name field dynamically by clicking the field binding icon and selecting your 'Brand' CMS field.
  5. Publish your site and validate the product page URL in Google's Rich Results Test.
Seo product missing gtinModerate effort

Add a valid GTIN (and/or MPN) to your Product structured data so Google can match your listings to its product catalog and show them in Shopping results and AI-powered product features.

On Webflow

  1. In the Webflow Designer, open your CMS Collections panel and select your Products collection.
  2. Add a new plain-text field named 'GTIN' (and optionally 'MPN') to the Products collection schema.
  3. Go to CMS → Content → Products and fill in the GTIN values for each product.
  4. Open your Product Template page in the Designer → add an 'Embed' element (HTML Embed) in the page's <head> or just before </body>.
  5. Inside the Embed, write a JSON-LD Product schema block and use Webflow's dynamic field binding syntax to pull in the GTIN collection field value: '"gtin": "[GTIN field binding]"'.
  6. Publish the site and verify with Google's Rich Results Test.
Seo product missing stock statusModerate effort

Add visible stock availability text to each product page and set the correct `availability` property (InStock, OutOfStock, or PreOrder) in your Product structured data (JSON-LD schema).

On Webflow

  1. Open your Webflow project in the Designer and navigate to your Product Template page (eCommerce → Products → Product Template).
  2. Webflow does not auto-generate Product JSON-LD schema, so you need to add it manually. Click the page settings gear for the Product Template page and scroll to 'Custom Code' → 'Inside <head> tag'.
  3. Paste a JSON-LD `<script>` block with a Product schema. Use Webflow CMS dynamic embed fields to pull in the product name, price, and availability dynamically (e.g. bind `availability` to a custom CMS field named 'Stock Status' that contains the full schema.org URL).
  4. Create a CMS field of type 'Option' on your Products collection called 'Schema Availability' with options: `https://schema.org/InStock` and `https://schema.org/OutOfStock`. Populate it for each product.
  5. For the visible label, add a Text element near the Add-to-Cart button on the Product Template, bind it to a CMS field (e.g. 'Availability Label' with plain-text values like 'In Stock'), and use conditional visibility to style it.
  6. Publish and verify with Google's Rich Results Test.
Seo product no imagesModerate effort

Add at least one high-quality image to every product page so Google can index it and shoppers can see what they're buying.

On Webflow

  1. Open the Webflow Designer and navigate to your CMS Collections → Products (or Ecommerce → Products if using Webflow Commerce).
  2. Click the product item that is missing an image.
  3. In the product record, click the image field (typically 'Main Image' or 'Product Images') and upload a new image from your computer.
  4. Once uploaded, fill in the 'Alt text' field that appears alongside the image upload.
  5. Publish the site. For Webflow Commerce, product images are included in the page's structured data if your product template is wired to the image field.
Seo product no spec tableModerate effort

Add a structured specifications table or list to every product page so search engines and AI tools can extract and surface factual product details, and shoppers can make faster buying decisions.

On Webflow

  1. Open the Webflow Designer and navigate to your Product Template page (eCommerce → Product Template in the Pages panel).
  2. Add a new Collection List element bound to the Product collection, or add a static Div block below the product description. Inside it, add an HTML Embed element or use Webflow's built-in grid/table layout.
  3. The cleanest approach: add custom fields to your Product CMS collection (CMS → Products → Add Field) for each spec (e.g., 'material', 'weight_grams'). Then drag a Multi-Reference or plain Text field element onto the Product Template canvas and bind it to the new spec fields.
  4. Style the bound fields as a two-column table using Webflow's Flexbox or Grid layout: left column = label (hard-coded text), right column = dynamic field value.
  5. For a true HTML <table>, use an HTML Embed element inside the Product Template and write a Webflow-templated table using {{wf {"path":"material"} }} dynamic binding syntax in the embed code.
  6. Publish the site and verify the spec table appears on all product pages by previewing several products with different spec values.
Seo product price not in htmlModerate effort

Render product prices in server-side HTML so search engines and rich-result parsers can read them without executing JavaScript.

On Webflow

  1. In the Webflow Designer, open your Product Template page (Ecommerce → Product Template).
  2. Ensure the price is bound to the CMS Product field using a native Webflow Text element with a dynamic binding to the 'Price' field — this renders server-side at publish time.
  3. Do NOT use Webflow's Embed element or custom JavaScript to fetch and display the price from an external source, as this will be JS-only and invisible to crawlers.
  4. For structured data, add a JSON-LD embed in the product template's <head> using Webflow's Page Settings → Custom Code (Head Code), binding the price value with a CMS embed tag if using Webflow CMS, or use a third-party Webflow SEO app like Semflow or Relume.
  5. After publishing, use View Page Source on a live product URL and confirm the price value appears in the raw HTML.
  6. If using Webflow's Ecommerce, verify the auto-generated structured data includes 'offers.price' by searching the page source for 'schema.org'.
Seo product single imageModerate effort

Add at least 4 high-quality product images (multiple angles, detail shots, and lifestyle/in-use photos) to every product listing to increase click-through rates and conversions.

On Webflow

  1. Open the Webflow Designer → navigate to the CMS (Ecommerce → Products) → click the product to open the collection item editor.
  2. Find the 'Main Image' and 'More Images' (or 'Gallery') multi-image fields. Click '+' or 'Choose File' to upload additional images.
  3. For each image, fill in the 'Alt Text' field within the image upload dialog.
  4. Publish the site after saving changes. Confirm the product template's gallery component is bound to the multi-image field so all uploaded images display.
Seo product title genericQuick win

Rewrite generic product page titles to include the product name plus at least one differentiating attribute (material, colour, size, pack size, or brand) in a natural, keyword-rich format.

On Webflow

  1. Open your Webflow project in the Designer.
  2. Navigate to the CMS → Collections → Products (or your product collection) → [select your product item].
  3. In the item editor, find the 'Slug & SEO Settings' section (or open the Collection item and look for the SEO fields at the bottom).
  4. Update the 'Title Tag' field with your optimised product title.
  5. Publish the project. Webflow writes this to the <title> tag for the product detail page.
  6. For template-level defaults, open the Product Template page in the Designer → Page Settings (cog icon) → SEO Settings → set a dynamic title using CMS fields, e.g. [Product Name] + [Category Field] + [Brand].
Seo variant urls in sitemapModerate effort

Remove product variant URLs (e.g. ?variant=, ?sku=) from your XML sitemap so only the canonical product page URL is submitted to Google.

On Webflow

  1. Webflow auto-generates a sitemap for CMS and Ecommerce collections. Go to Webflow Designer → Project Settings → SEO tab — confirm 'Auto-generate sitemap' is enabled and review which Collection pages are included.
  2. Webflow Ecommerce product variants do not generate separate URLs by default (variant selection is handled client-side). If variant query-parameter URLs appear in your sitemap, a custom code embed or third-party script is adding them.
  3. Check any Custom Code added in Project Settings → Custom Code or in the product template page's before-</body> section for scripts that append variant parameters to the URL bar.
  4. To exclude specific URL patterns from being crawled, go to Project Settings → SEO → Edit Robots.txt and add a Disallow rule for the query parameter pattern (e.g., Disallow: /*?variant=). Note: this prevents crawling but the sitemap must also be clean.
  5. After fixing, republish your site (Publish button) to regenerate the sitemap, then resubmit in Google Search Console.
Seo variant urls not canonicalizedModerate effort

Add a canonical tag to every product variant URL pointing back to the base product page, so Google consolidates ranking signals onto one authoritative URL instead of splitting them across hundreds of near-duplicate pages.

On Webflow

  1. In Webflow, CMS-powered product pages with variant query strings (added via custom code or integrations) require you to set the canonical in the Collection page template.
  2. Open the Webflow Designer → navigate to your Product Collection Template page.
  3. Click the page settings gear icon (top-left) → SEO Settings → 'Canonical Tag'. Set this to the base product URL using the CMS dynamic field (e.g. bind it to the Product Slug field to produce https://www.yourstore.com/products/[slug]).
  4. If your canonical field is not available in page SEO settings, go to Project Settings → Custom Code → add a canonical <link> tag in the 'Head Code' section using a Webflow CMS embed with the slug dynamic field on the Collection page.
  5. Publish the site and verify with View Page Source on a variant URL that the canonical href resolves to the clean product URL.
Slow pageLarger project

Reduce page load time to under 3 seconds by compressing images, minifying CSS/JS, enabling caching, and improving server response speed.

On Webflow

  1. Images: In the Webflow Designer, select each image element → click the image → replace with a compressed version. Use the Asset Manager (left panel → Assets) to upload WebP images. Enable 'Lazy load' in the image element settings panel (right-side Element Settings → Lazy load toggle ON) for all below-fold images.
  2. Webflow automatically minifies HTML, CSS, and JS on publish — no manual action needed. Ensure 'Minify HTML' is checked in Project Settings → Publishing.
  3. Custom code: In Project Settings → Custom Code, audit any scripts in the <head> or before </body>. Add 'defer' attribute to third-party scripts in the body section.
  4. Fonts: In Project Settings → Fonts, remove unused Google Fonts or Adobe Fonts. Each font family/weight is a separate network request. Prefer using system font stacks where design allows.
  5. Apps/Integrations: In Apps & Integrations (left sidebar), remove any Webflow apps not in active use.
  6. CDN: Webflow hosts all sites on AWS CloudFront CDN — no configuration needed. For further performance gains, reduce animations (Interactions panel) above the fold and minimize use of Lottie animations on critical pages.
Thin contentModerate effort

Expand thin pages to at least 300 words of unique, helpful content that genuinely describes your products, category, or topic.

On Webflow

  1. Product pages: Webflow Designer → CMS → Collections → Products → [select product] → expand the 'Description' rich text field and add full content. Bind this field to a Rich Text element on the Product Template page in the Designer.
  2. Category pages: Create a CMS Collection for categories with a 'Body' rich text field, populate it with the category description, and bind it to a Rich Text block on your Category Template page.
  3. For auto-generated filter or tag pages, use Webflow's Page Settings (gear icon on the page) → SEO tab → check 'Exclude from search results' (noindex) for any thin generated pages.
Title too longQuick win

Shorten your page title tag to 60 characters or fewer so it displays in full — not truncated — in Google search results.

On Webflow

  1. Open your project in the Webflow Designer.
  2. For a static page: click the Pages icon (top-left) → hover over the page → click the Settings gear → scroll to 'SEO Settings' → edit the 'Title Tag' field; a live character count is displayed.
  3. For a CMS Collection item (e.g. a product or blog post): go to the CMS panel → open the Collection → select the item → update the 'SEO Title' field in the item's settings pane.
  4. To set a default title template for all items in a Collection: CMS → Collection Settings → SEO tab → edit the Title field using dynamic bindings (e.g. {{Name}} – Brand Name) and keep the static text short.
  5. After editing, publish the site (Publish button, top-right) for changes to go live.
Title too shortQuick win

Expand your page title to between 50 and 60 characters so it displays fully in Google search results and gives shoppers a clear reason to click.

On Webflow

  1. Open the Webflow Designer and select the page you want to edit from the Pages panel.
  2. Click the gear icon (⚙) next to the page name to open Page Settings.
  3. In the 'SEO Settings' section, update the 'Title Tag' field with your new 50–60 character title.
  4. Click 'Save' and then publish the site (Publish → Publish to your domain) for the change to go live.
  5. For CMS collection items (e.g., products or blog posts), open the CMS Collection, edit the item, and update the 'SEO Title' field in that item's settings panel.

Answer Engine Optimization · 15 fixes

Article missing authorModerate effort

Add a structured-data author field (schema.org Person) to every article and blog post so AI engines and search crawlers can verify who wrote the content.

On Webflow

  1. Open your Webflow project and navigate to the CMS → Blog Posts collection.
  2. Add a plain-text field called 'Author Name' and a URL field called 'Author Profile URL' (for sameAs) if they don't exist; populate them for all posts.
  3. Open the Designer, select the Blog Post template page, and add an 'Embed' element (HTML Embed) just before the closing </body> tag.
  4. Paste the JSON-LD code example into the embed, replacing static values with Webflow CMS dynamic bindings: use the + button to bind 'Author Name' and 'Author Profile URL' fields into the JSON string.
  5. Publish the site and test a live blog post URL in Google's Rich Results Test.
Invalid rating valueModerate effort

Fix the AggregateRating.ratingValue in your structured data so it falls within the valid numeric range (1–5 by default, or within the declared bestRating/worstRating bounds).

On Webflow

  1. In the Webflow Designer, select the page containing product/review structured data.
  2. Open Page Settings (gear icon) > Custom Code > Head Code, and locate your existing JSON-LD AggregateRating block.
  3. Update the ratingValue to a valid number between worstRating and bestRating (e.g. between 1 and 5). If the value is dynamically bound via CMS, open the CMS Collection, find the Rating field, and ensure no item has a value below 1 or above 5.
  4. Add "worstRating": "1" and "bestRating": "5" to the JSON-LD if not already present.
  5. Publish the site and validate with the Rich Results Test.
Low answer first scoreModerate effort

Restructure your page content to lead with a direct, concise answer and add FAQ schema so search engines and AI assistants can surface your content as a featured snippet or direct answer.

On Webflow

  1. Open the Designer, navigate to the target page, and select the first text element in the main content area.
  2. Edit the copy to begin with a concise direct-answer summary paragraph.
  3. Change existing section heading text to question format and ensure they use H2 or H3 tags (set via the Element Settings panel → Tag dropdown).
  4. For FAQ schema: in the Page Settings panel (the gear icon next to the page in the Pages panel), scroll to 'Custom Code' → 'Before </body> tag' and paste the FAQPage JSON-LD <script> block.
  5. If using Webflow CMS for FAQ content, add a JSON-LD embed element on the collection template and use dynamic bindings to pull question/answer fields into the schema.
  6. Publish the site and verify with Google's Rich Results Test.
Low review countModerate effort

Collect at least 5 published reviews so Google can display star ratings in search results for your product pages.

On Webflow

  1. Webflow Ecommerce does not have a native review system; install a third-party review widget such as Trustpilot, Judge.me, or Stamped via an embed code block.
  2. In the Webflow Designer, open the Product Template page, add an 'Embed' element in the product detail section, and paste your review app's widget code.
  3. Confirm your chosen review app outputs aggregateRating JSON-LD or add it manually in Page Settings → Custom Code → Head Code using a CMS-bound script that reads the review count field.
  4. Create a review-request automation within your review app's dashboard, triggered by order fulfilment events via Zapier or a native integration.
  5. Once 5 reviews are published and the schema reflects reviewCount ≥ 5, validate with the Rich Results Test.
Missing schema articleModerate effort

Add Article and BreadcrumbList JSON-LD structured data to every editorial/blog page so search engines and AI answer engines can correctly identify, understand, and feature your content.

On Webflow

  1. In the Webflow Designer, open your Blog Post Collection Template page.
  2. In the Page Settings panel (click the gear icon while on the template page) › Custom Code › Head Code — paste your Article JSON-LD <script> block here, using Webflow's CMS dynamic embed syntax to insert collection field values: wrap field references in %% or use Webflow's 'Embed' element for richer dynamic output.
  3. For fully dynamic schema (recommended), drag an 'Embed' HTML element onto the blog post template canvas, then use Webflow's 'Add Field' picker inside the embed to bind CMS fields (Post Title, Author, Publish Date, Slug) directly into your JSON-LD template.
  4. For BreadcrumbList, add a second Embed element and bind the post's collection name and slug to build the three-level breadcrumb (Home › Blog › Post Title).
  5. Publish the site and validate a live blog post URL with Google's Rich Results Test.
Missing schema breadcrumblistModerate effort

Add BreadcrumbList structured data (JSON-LD) to every page so Google can display your site's navigation path directly in search results.

On Webflow

  1. Open your Webflow project in the Designer. Select the page you want to edit from the Pages panel.
  2. Open Page Settings (click the gear icon next to the page name) → scroll down to the 'Custom Code' section → paste your <script type="application/ld+json"> BreadcrumbList block into the 'Before </body> tag' or 'Inside <head> tag' field.
  3. For Collection pages (CMS-driven product or category pages), use Webflow's CMS bindings: in the Custom Code field, reference CMS field slugs using Webflow embed code expressions so the breadcrumb name and item URL update automatically for each collection item.
  4. For a more scalable approach, add an 'HTML Embed' element inside your Collection page template and bind CMS fields to dynamically construct the JSON-LD.
  5. Publish the site, then validate a live Collection item URL in Google's Rich Results Test.
Missing schema faqpageModerate effort

Add FAQPage (and BreadcrumbList) JSON-LD structured data to pages that contain FAQ content so Google can display rich results directly in search.

On Webflow

  1. Open the Webflow Designer and navigate to the page with FAQ content.
  2. Click the page Settings icon (wrench icon at top of the Pages panel) › Custom Code tab.
  3. In the 'Before </body> tag' section, paste your <script type='application/ld+json'> FAQPage block.
  4. Add your BreadcrumbList JSON-LD block in the same field (use separate <script> tags for each schema type).
  5. For CMS-driven FAQ pages: use Webflow CMS collections for Q&A content, then use an Embed element inside the CMS Collection template with Webflow's dynamic binding to pull question/answer fields into the JSON-LD — this keeps schema in sync with your content automatically.
  6. Publish the site and validate with Google's Rich Results Test.
Missing schema howtoModerate effort

Add HowTo and BreadcrumbList structured data (JSON-LD) to pages that contain step-by-step instructions so Google can display them as rich results and answer-engine snippets.

On Webflow

  1. Open the page in the Webflow Designer.
  2. Click the Page Settings gear icon (top-right of the canvas) › Custom Code tab.
  3. Paste the <script type='application/ld+json'>…</script> block into the 'Inside <head> tag' or 'Before </body> tag' field for that specific page.
  4. For CMS Collection pages (e.g. a 'Guides' collection): open the Collection Template, go to Page Settings › Custom Code, and use Webflow CMS dynamic field bindings (e.g. {{Name}}, {{Steps}}) inside the JSON-LD to populate schema dynamically for each guide.
  5. Publish the site and validate with Google's Rich Results Test.
Missing schema localbusinessQuick win

Add a LocalBusiness JSON-LD schema block to your store so search engines and AI assistants can surface your business name, address, phone number, and hours in rich results and answer boxes.

On Webflow

  1. In the Webflow Designer, open Project Settings (the gear icon at the top left).
  2. Go to the Custom Code tab.
  3. Paste your <script type='application/ld+json'>…</script> block into the 'Head Code' field (this adds it to every page).
  4. Click Save Changes, then Publish your site.
  5. For page-specific schema (e.g. only on the Contact page), open that page's settings in the Pages panel, scroll to Custom Code, and paste the block into the page-level Head Code field instead.
Missing schema organizationQuick win

Add Organization schema markup to your store's homepage so search engines and AI systems can definitively identify your business, logo, and social profiles.

On Webflow

  1. Open your Webflow project in the Designer.
  2. Click the 'W' (Project Settings) icon → go to the 'Custom Code' tab.
  3. In the 'Head Code' section, paste your <script type='application/ld+json'>…</script> block.
  4. Click 'Save Changes' and publish your site.
  5. Validate by running your homepage URL through Google's Rich Results Test.
Missing schema productModerate effort

Add Product schema (JSON-LD structured data) to every product page so search engines can display rich results like price, availability, and ratings directly in search listings.

On Webflow

  1. Open your Webflow project in the Designer. Navigate to your CMS Product template page (usually named 'Product Template' under CMS Collection Pages in the Pages panel).
  2. In the Page Settings for that template page, scroll to 'Custom Code' → 'Before </body> tag' section.
  3. Paste a <script type='application/ld+json'> block. Use Webflow CMS dynamic embed fields by inserting CMS bindings — click the '+' Add Field button inside the code block to reference fields like Product Name, Price, Description, Main Image, etc.
  4. Set availability dynamically: if your CMS collection has a stock/availability field, bind it; otherwise hardcode a default and update manually or via Webflow Zapier integration.
  5. Publish the site and validate a live product URL with Google's Rich Results Test.
Missing schema webpageModerate effort

Add WebPage (and Organization) JSON-LD schema markup to every page so search engines and AI answer engines can confidently understand and describe your site's content.

On Webflow

  1. Open your project in the Webflow Designer. For sitewide Organization schema: go to Project Settings → Custom Code → Head Code. Paste your Organization JSON-LD <script> block here and publish.
  2. For per-page WebPage schema: select the target page in the Pages panel → click the gear icon → SEO Settings → and use the 'Custom Code' → Head Code field for that page to paste the WebPage JSON-LD block.
  3. Use Webflow CMS dynamic fields (e.g. {Name}, {Slug}) inside JSON-LD blocks on Collection page templates so schema values update automatically for every item (blog post, product, etc.).
  4. Publish the site and validate representative pages using Google's Rich Results Test.
Non iso dateModerate effort

Change all datePublished (and dateModified) values in your structured data from informal formats like "09/23/2019 00:00:00" to the ISO-8601 format "2019-09-23" so search engines can correctly read your content's publication date.

On Webflow

  1. In the Webflow Designer, open the Page Settings for any page that has custom JSON-LD structured data added in the 'Custom Code' → 'Head Code' or 'Before </body> tag' sections.
  2. Locate any date fields in those JSON-LD blocks and correct the value to ISO-8601 format: '2019-09-23' or '2019-09-23T00:00:00Z'.
  3. For CMS-driven pages (Blog Posts, Products), open the CMS Collection schema under CMS → Collections, and check if you have a Date field connected to a JSON-LD embed in the Collection Template page.
  4. In the Collection Template page's custom code embed, use Webflow's CMS field binding to pull the date dynamically. Ensure the bound Date field outputs in ISO format — Webflow Date fields can be formatted; use the 'YYYY-MM-DD' format option in the embed binding dialog.
  5. If dates are hard-coded in embeds, update each one manually to the correct ISO format.
  6. Publish the site and test affected pages in Google's Rich Results Test.
Org missing sameasQuick win

Add a `sameAs` array to your Organization structured data, linking to your official social profiles, Wikipedia page, LinkedIn, and other authoritative directories so search engines can confidently identify your brand as a distinct entity.

On Webflow

  1. In the Webflow Designer, open your Project Settings → Custom Code tab.
  2. Paste the Organization JSON-LD block (with `sameAs`) into the 'Head Code' field.
  3. Publish the site, then verify with Google's Rich Results Test.
Page unreachableModerate effort

Ensure every page that should appear in AI-powered answers and rich results is actually reachable by crawlers, then add structured data so search engines and AI systems can read and surface its content.

On Webflow

  1. In the Webflow Designer, confirm the page is published: go to Pages panel → right-click the page → Page Settings → ensure it is not set to 'Exclude from search index' (noindex) and is published in the current project.
  2. Check Project Settings → SEO → confirm 'Disable Webflow subdomain indexing' or any global noindex setting is not accidentally applied to production.
  3. For broken CMS collection item URLs, check the CMS Collections panel — confirm the item is set to 'Published' (not 'Draft' or 'Archived') and the slug matches the expected URL.
  4. For redirects, go to Project Settings → Hosting → Redirects and add a 301 redirect from the broken path to the correct live URL.
  5. To add structured data, open the page in the Designer → Add an Embed element (from the Add panel → Components → Embed) → paste your JSON-LD <script> block directly. For CMS-driven pages, use dynamic binding inside the Embed element to pull in product name, price, etc. from Collection fields.
  6. Publish the site, then submit in Google Search Console and verify with the Rich Results Test.

Accessibility (WCAG) · 63 fixes

Aria allowed attrModerate effort

Remove or replace any ARIA attributes that are not permitted on an element's assigned role so that assistive technologies can correctly interpret the element.

On Webflow

  1. Open your project in the Webflow Designer; select the element flagged by the scanner in the Navigator panel.
  2. In the right-hand Element Settings panel (the gear icon), scroll to the Custom Attributes section — this is where ARIA attributes are added manually.
  3. Identify the disallowed `aria-*` attribute, remove it by clicking the '×' next to it, or change the element's role attribute to one that supports the ARIA attribute you need.
  4. If the element's role itself is wrong (set in the same Custom Attributes section), update it to the correct role and adjust the accompanying ARIA attributes to match.
  5. Publish the site and re-test with the axe DevTools browser extension.
Aria allowed roleModerate effort

Remove or replace the invalid `role="presentation"` (or other disallowed ARIA role) on HTML elements where that role is not permitted, so assistive technologies can correctly interpret your page.

On Webflow

  1. Open your project in the Webflow Designer and select the flagged element in the Navigator panel.
  2. In the right-hand Settings panel (gear icon), scroll to the Custom Attributes section.
  3. Look for a `role` attribute entry — if it contains a disallowed value (e.g., `presentation` on a Link Block or Button element), delete that attribute row entirely or change the value to a permitted role.
  4. If no custom attribute is present, check the element's HTML tag: switching from a semantic element (e.g., Button) to a Div may resolve the conflict; alternatively, simply remove the role attribute.
  5. Publish the project and verify with axe DevTools or Lighthouse.
Aria command nameModerate effort

Add a discernible, screen-reader-accessible name to every button, link, and menuitem that uses an ARIA command role so assistive technology can announce what it does.

On Webflow

  1. Open the Webflow Designer for your project.
  2. Select the unlabelled button, link block, or icon element in the canvas.
  3. In the right-hand Settings panel (gear icon), scroll to the 'Accessibility' section and fill in the 'Aria Label' field with a short, descriptive phrase (e.g., 'Open navigation menu').
  4. For elements containing only an SVG, also select the SVG element and in its Settings panel set 'Aria Hidden' to 'true' so screen readers skip the decorative graphic.
  5. Publish the project and verify with axe DevTools in your browser.
Aria dialog nameModerate effort

Add a descriptive accessible name to every dialog and alertdialog element using aria-label or aria-labelledby so screen-reader users know what the dialog is about.

On Webflow

  1. In the Webflow Designer, select the Modal or Div Block that serves as your dialog.
  2. Open the Element Settings panel (D key) → Custom Attributes section.
  3. Click '+' to add a new attribute: set Name to role and Value to dialog (if not already set).
  4. Add another attribute: set Name to aria-labelledby and Value to the ID of the heading element inside the dialog (e.g. cart-dialog-title). Make sure the heading element has that ID set in its Element Settings.
  5. If there is no visible heading, instead add aria-label with a descriptive value like Shopping cart.
  6. Publish the site and verify with axe DevTools or a screen reader.
Aria hidden focusModerate effort

Remove `aria-hidden="true"` from any element that contains focusable children (links, buttons, inputs), or remove the focusable elements from inside the hidden container.

On Webflow

  1. Open the Webflow Designer for your project.
  2. Select the element flagged by the scanner. In the right-hand Settings panel (the gear icon), scroll to the 'Custom Attributes' section.
  3. If `aria-hidden` is set to `true` on a Div Block or Section that wraps a Button, Link, or Form element, either delete the `aria-hidden` attribute from that element, or restructure the layout so focusable elements are moved outside the hidden container.
  4. For Symbols/Components: open the Symbol editor, make the fix inside the symbol, then save — the change will propagate to all instances.
  5. Publish the site and verify with the axe DevTools browser extension on the published URL.
Aria input field nameModerate effort

Add a meaningful accessible name (label) to every ARIA input field so screen readers can identify and announce it to users.

On Webflow

  1. Open your Webflow project in the Designer and select the Form Block or specific Input element that is missing a label.
  2. In the right-hand Settings panel for the Input element, find the 'Label' toggle — enable it and fill in a descriptive label text. Webflow will render a proper <label> element linked to the input.
  3. If a visible label is not desired for design reasons, keep the label hidden visually: select the Label element, go to Style panel → add a class (e.g., 'visually-hidden') and apply CSS: position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; — this hides it visually while keeping it accessible.
  4. Alternatively, select the Input element → Settings panel → Custom Attributes section → add a new attribute: Name = aria-label, Value = 'Your descriptive label text'.
  5. Publish the site and verify using the axe DevTools browser extension.
Aria meter nameModerate effort

Add a descriptive accessible name (via aria-label, aria-labelledby, or a visible <label>) to every element that uses role="meter" so screen readers can announce what the meter represents.

On Webflow

  1. Open the Webflow Designer and select the element that has role='meter' (e.g. a progress bar or star widget).
  2. In the right-hand panel, click the 'Element Settings' tab (the gear icon).
  3. Scroll to the 'Custom Attributes' section, click the '+' button, add Name: `aria-label` and Value: `Average customer rating` (or the relevant description).
  4. If using a CMS collection for products, use a dynamic bind: set the Value to a CMS field like the product name + ' rating' using Webflow's CMS binding on the attribute.
  5. Publish and verify with axe DevTools.
Aria progressbar nameQuick win

Add a descriptive accessible name to every progress bar element so screen readers can announce what it represents.

On Webflow

  1. In the Webflow Designer, click the progress bar element (a `<progress>` tag or a div with `role="progressbar"`) to select it.
  2. Open the Element Settings panel (the gear icon) → Custom Attributes section.
  3. Add a new attribute: Name = `aria-label`, Value = your descriptive text (e.g., `Password strength`). Or add `aria-labelledby` pointing to the ID of a nearby visible label element.
  4. Also add `aria-valuenow`, `aria-valuemin`, and `aria-valuemax` attributes here if they are not already present.
  5. If the bar is controlled by a CMS collection, use a CMS field reference in the attribute value so the label is dynamic.
  6. Publish the site and verify in Chrome DevTools → Accessibility tab.
Aria prohibited attrModerate effort

Remove or replace ARIA attributes that are explicitly prohibited on an element's assigned role, ensuring every ARIA attribute used is valid for its context.

On Webflow

  1. Open your project in the Webflow Designer. Select the element flagged by your scanner.
  2. In the right-hand panel, open the Element Settings tab (the gear icon). Scroll to 'Custom Attributes' — this is where manually added ARIA attributes live.
  3. Locate the prohibited ARIA attribute in the custom attributes list and either delete it or replace the element's role with one that allows the attribute.
  4. If the element's role itself needs to change, update the `role` custom attribute value to a role that is compatible with the ARIA attribute you want to keep.
  5. For elements rendered by Webflow CMS collections, open the Collection Template page in the Designer and apply the same fix to the bound element.
  6. Publish the site and verify with the axe DevTools browser extension.
Aria required attrModerate effort

Add the required `aria-level` attribute (and any other missing required ARIA attributes) to every element that uses an ARIA role which mandates them.

On Webflow

  1. Open the Webflow Designer. Select the element flagged (e.g., a Div Block acting as a heading).
  2. In the right-hand Settings panel (the gear icon), scroll to the Custom Attributes section.
  3. Add the missing attribute: set the Name field to `aria-level` and the Value field to the correct integer (e.g., `2`). Click the + button to save it.
  4. Consider switching the element's HTML tag to a native heading tag (H1–H6) via the Tag dropdown at the top of the Settings panel — this makes the `role` and `aria-level` attributes unnecessary.
  5. Publish the site and verify with the axe DevTools browser extension.
Aria required childrenModerate effort

Ensure every ARIA parent role contains only its required, permitted child roles — and remove focusable elements (e.g. tabindex on img or a) that are not allowed inside that ARIA context.

On Webflow

  1. Open the Webflow Designer and select the element that is the ARIA parent (the element with the role= attribute).
  2. In the right-hand Settings panel (the gear icon), scroll to the Custom Attributes section. Review the role value and ensure its child elements carry the correct child roles.
  3. Select each child element and, in its own Settings panel Custom Attributes, add the required role attribute (e.g. role: menuitem for children of a menu).
  4. To fix tabindex on an img or a inside a restricted parent: select the child element → Settings → Custom Attributes, find tabindex and delete it, or move the focusable behavior to a correctly-roled wrapper element.
  5. Prefer Webflow's native semantic elements (Navbar, List, List Item) over custom div+role combinations — they output the correct ARIA structure automatically.
  6. Publish and verify with axe DevTools in your browser.
Aria required parentModerate effort

Wrap every ARIA child role (such as `tab`, `option`, `listitem`, `row`, etc.) in the correct required ARIA parent container role (such as `tablist`, `listbox`, `list`, `rowgroup`, or `grid`) so assistive technologies can correctly interpret the widget's structure.

On Webflow

  1. In the Webflow Designer, select the parent container element of the flagged child role elements.
  2. Open the Element Settings panel (D key) → scroll to Custom Attributes → add Attribute Name: `role`, Value: `tablist` (or the appropriate required parent role).
  3. For Webflow's built-in Tabs component, the `tablist` role is typically set by Webflow automatically — if the scanner flags it, check whether a custom interaction or CSS is hiding/restructuring the DOM and breaking the hierarchy.
  4. If the widget is a custom component or Symbol, edit the Symbol and add the custom attribute to the correct wrapper div.
  5. Publish the site and verify using Chrome DevTools → Accessibility panel that the role hierarchy is intact.
Aria rolesModerate effort

Audit every element that has a `role` attribute and replace any invalid, misspelled, or non-existent ARIA role value with a valid WAI-ARIA role from the official specification.

On Webflow

  1. Open the Webflow Designer for your project. Select the element with the invalid ARIA role.
  2. In the right-hand panel, click the 'Element Settings' tab (the gear icon). Scroll down to the 'Accessibility' section.
  3. Find the 'ARIA role' dropdown or text field. Replace the invalid value with a correct WAI-ARIA role from the dropdown list, or clear it if a native semantic element is being used.
  4. For elements inside Components or Symbols, open the component in edit mode to change the role at the component level so all instances are fixed.
  5. Publish your site and verify the fix with axe DevTools in the browser.
Aria toggle field nameModerate effort

Give every toggle control (checkbox, switch, or ARIA toggle button) a descriptive accessible name so screen readers can announce what it does.

On Webflow

  1. In the Webflow Designer, select the checkbox or toggle element on the canvas.
  2. Open the Element Settings panel (the gear icon on the right sidebar).
  3. Scroll to the 'Accessibility' section and fill in the 'Label' (aria-label) field with a descriptive name.
  4. For checkboxes that already have a visible text label next to them, ensure the label element is properly nested or linked: Webflow's native Checkbox component wraps the input in a label by default — confirm the label text is set in the element's text node.
  5. For custom toggle components built with Div blocks, add a custom attribute: in the Element Settings panel → Custom Attributes, add Name: aria-label, Value: 'Your descriptive label'.
  6. Publish the site and test with the axe DevTools browser extension.
Aria tooltip nameModerate effort

Add a visible, descriptive text label to every element that has role="tooltip" so screen readers can announce its purpose.

On Webflow

  1. Open your Webflow Designer and select the element that has the tooltip behavior (often a div or span with a custom interaction or the Webflow 'Tooltip' component).
  2. In the right-hand Settings panel, click the 'Accessibility' section (the person icon). Add a descriptive label in the 'aria-label' field, e.g., 'Add to wishlist'.
  3. If the tooltip is a separate element in the DOM with role="tooltip", select that element, open the Element Settings panel (D key), scroll to Custom Attributes, and add: Name = aria-label, Value = [your descriptive text].
  4. Alternatively, ensure the tooltip element contains a visible Text element as a child — Webflow will use that text as the accessible name automatically.
  5. Publish the site and verify with the axe DevTools browser extension or a screen reader.
Aria valid attrModerate effort

Find every misspelled or non-existent ARIA attribute name in your HTML (e.g. `aria-labeledby` instead of `aria-labelledby`) and correct each one to a valid ARIA attribute name.

On Webflow

  1. Open your project in the Webflow Designer. Select the element with the invalid ARIA attribute.
  2. In the right-hand panel, go to Element Settings (the gear icon) → Custom Attributes section.
  3. Find the misspelled attribute (e.g. `aria-labeledby`) in the custom attributes list. Click it to edit the Name field and correct the spelling to `aria-labelledby` (or the correct name). Do NOT change the Value.
  4. For elements where the ARIA attribute is set by a Webflow interaction or CMS binding, check the Interactions panel and any CMS collection field mappings.
  5. Publish your site and re-run axe DevTools to confirm.
Aria valid attr valueModerate effort

Audit every ARIA attribute on your pages and correct any that point to a non-existent element ID, use a disallowed value, or reference an empty/misspelled target so that assistive technologies can correctly interpret your page.

On Webflow

  1. Open your project in the Webflow Designer.
  2. Select the element with the invalid ARIA attribute in the Navigator or on the canvas.
  3. In the right-hand panel, click the Element Settings tab (the gear icon) and scroll to the Custom Attributes section.
  4. Find the offending ARIA attribute (e.g., aria-labelledby) and correct its value — ensure it matches the exact ID of another element on the page, or change the keyword to an allowed value.
  5. To find/set the ID of the target element, select that element → Element Settings → ID field.
  6. Publish the site, then run an axe DevTools audit on the live URL to confirm the fix.
Autocomplete validModerate effort

Add a valid, correctly matched `autocomplete` attribute to every personal-data form field so browsers and assistive technologies can autofill them reliably.

On Webflow

  1. Open the Webflow Designer and select the Form element on the canvas.
  2. Click on the specific Input field inside the form to select it.
  3. In the right-hand Settings panel (the gear icon), scroll to the Custom Attributes section at the bottom.
  4. Click the '+' button to add a new attribute; set the Name to 'autocomplete' and the Value to the correct token (e.g., 'given-name', 'email', 'postal-code').
  5. Repeat for every personal-data input in the form, then Publish the site and verify with a browser autofill test.
Avoid inline spacingModerate effort

Remove hard-coded text-spacing CSS properties from inline `style` attributes so users can override them with their own stylesheets.

On Webflow

  1. Open the Designer and select the element flagged for inline spacing.
  2. In the Style panel (right sidebar), check the Typography section for any overrides to Line Height, Letter Spacing, or Word Spacing set directly on this element rather than on a class.
  3. If the values are element-level overrides (shown in blue/highlighted), remove them by clicking the property and pressing Delete/Backspace, or by right-clicking the property and choosing 'Remove override'. This ensures the value comes from the class rule, not an inline style.
  4. Define correct spacing values on the element's CSS class (create one if the element has none) so the rule lives in the stylesheet.
  5. For CMS-driven content where spacing is set via a Rich Text block, apply global Rich Text styles in the Style panel on the Rich Text class rather than inside the editor.
  6. Publish the site and verify with the axe browser extension.
Button nameModerate effort

Add a visible or programmatically accessible name to every button so screen readers can announce what it does.

On Webflow

  1. Open the Webflow Designer. Select the button element on the canvas.
  2. In the right-hand Settings panel (the gear icon), scroll to the 'Accessibility' section. Enter a descriptive label in the 'ARIA Label' field — Webflow natively supports this for Button elements.
  3. For icon-only buttons built with a Div + click interaction (not a semantic Button element), change the element to a Button tag via the Element settings, then set the ARIA Label.
  4. If the button contains an SVG, select the SVG in the designer and in its Settings panel set 'aria-hidden' to 'true' so the label on the button is the sole accessible name.
  5. Publish the site and verify with axe DevTools.
Color contrastModerate effort

Increase the contrast ratio between your text color and its background color to at least 4.5:1 so all users — including those with low vision — can read your content.

On Webflow

  1. Open the Webflow Designer and select the element with the failing text color.
  2. In the right-side Style panel, locate the Color property under Typography and click the color swatch. Enter a hex value that passes 4.5:1 (e.g. darken your blue until it passes).
  3. If the color comes from a Webflow Global Swatch (Style Guide → Color Swatches), update the swatch directly — the change will propagate to every element using it.
  4. Publish and re-test with an axe DevTools browser extension or Lighthouse.
Definition listModerate effort

Fix all `<dl>` (definition list) elements so they contain only valid `<dt>` and `<dd>` child elements, in the correct order, with no stray tags or text directly inside the list wrapper.

On Webflow

  1. Open the Webflow Designer for the affected page. In the Navigator panel (left sidebar), locate the 'Definition List' element (Webflow maps this to `<dl>`).
  2. Click on the `<dl>` element and inspect its children in the Navigator. Webflow natively supports 'Definition Term' (`<dt>`) and 'Definition Description' (`<dd>`) element types — ensure only these are nested directly inside the list.
  3. If extra elements (e.g., a Text Block or Paragraph) were accidentally dropped inside the `<dl>`, drag them out above or below the list in the Navigator.
  4. To add a valid grouping `<div>` wrapper around `<dt>`+`<dd>` pairs, add a 'Div Block' inside the `<dl>` and nest the term and description inside it.
  5. Publish the site and verify with axe DevTools or WAVE in the browser.
DlitemQuick win

Wrap every `<dt>` (term) and `<dd>` (description) element inside a parent `<dl>` element so screen readers can correctly announce the list structure.

On Webflow

  1. Open your project in the Webflow Designer and navigate to the page with the flagged element.
  2. In the Navigator panel (left sidebar), find the element containing the `<dt>` or `<dd>` tag. Webflow uses 'Definition Term' and 'Definition Description' element types, which are built-in.
  3. Select the parent container of the orphaned `<dt>`/`<dd>` element. In the Element Settings panel (right sidebar), check its tag. If it is not `<dl>`, click the tag selector and change it to `DL` (Description List).
  4. Alternatively, delete the orphaned items and re-add them properly: in Add Elements (left sidebar, +), search for 'Definition List' and drag it onto the canvas, then add 'Definition Term' and 'Definition Description' elements inside it.
  5. Publish the site and verify with axe DevTools.
Document titleQuick win

Add a unique, descriptive <title> element to every page so browsers, screen readers, and search engines can identify it.

On Webflow

  1. Open your project in the Webflow Designer.
  2. Click the Pages panel (the page icon in the left toolbar) and select the page you need to fix.
  3. Click the settings gear (⚙) icon next to the page name to open Page Settings.
  4. Under the 'SEO Settings' section, fill in the 'Title Tag' field with a descriptive, unique title.
  5. For CMS Collection pages (e.g. Products, Blog): open the Collection template page settings → in the Title Tag field, use dynamic CMS fields — e.g. type the product name field binding so every item gets a unique title automatically.
  6. Publish the site, then open the live page and confirm the browser tab shows the correct title.
Empty headingModerate effort

Find every empty heading tag on your store and add meaningful, visible text to it — or remove the tag entirely if it serves no structural purpose.

On Webflow

  1. In the Webflow Designer, open the page and use the Navigator panel (left sidebar, stacked-boxes icon) to view all elements in the page tree.
  2. Look for Heading elements (H1–H6) with no text label in the Navigator. Click each to select it on the canvas.
  3. In the element settings on the right, either type content directly into the heading on the canvas or delete the element if it has no structural purpose.
  4. If an empty heading is used purely for CSS styling/spacing, replace it by changing its tag to a `<div>` in the Element Settings panel (right sidebar → Tag dropdown) and apply the same styles.
  5. For headings that contain only an icon (SVG), select the Heading element, add a Text node inside it, type a descriptive label, and then visually hide it using a custom 'sr-only' class (position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0,0,0,0)).
  6. Publish and verify with axe DevTools.
Empty table headerModerate effort

Add descriptive text to every table header cell (`<th>`) so that screen readers can announce what each column or row represents.

On Webflow

  1. Open your project in the Webflow Designer. Select the Table element on the canvas that contains the empty header.
  2. Click the empty `<th>` cell in the Designer. In the right-hand panel, type the column label text directly into the cell on the canvas.
  3. If the header must remain visually blank (e.g., a spacer), open the element's Settings panel (the gear icon) and add an `aria-label` attribute under the Custom Attributes section — set Name to `aria-label` and Value to the descriptive label (e.g., `Thumbnail`).
  4. Also add a `scope` custom attribute with value `col` or `row` as appropriate.
  5. Publish your changes and re-test with the WAVE or axe DevTools browser extension on the live site.
Frame titleQuick win

Add a descriptive `title` attribute to every `<iframe>` element on your store so screen readers can identify the frame's content.

On Webflow

  1. Open your project in the Webflow Designer.
  2. For a native Webflow Embed element: click the element on the canvas → click 'Open Embed Code' in the right-hand settings panel.
  3. In the embed code editor, find the `<iframe>` tag and add `title="Your descriptive label"`, then click 'Save & Close'.
  4. For a Webflow Video element (YouTube/Vimeo): there is currently no built-in title field. Instead, publish the site, then add a custom script via Project Settings → Custom Code → Footer Code (or Page Settings → Before </body> tag): `<script>document.querySelectorAll('iframe:not([title])').forEach(function(el){ el.title = 'Embedded video'; });</script>` — use a more specific label if you know the content.
  5. For interactions or components created with components/symbols: open the Symbol, edit the embed code there, and add the title attribute so all instances are updated at once.
  6. Publish, then open the live site in your browser and inspect iframes in DevTools to verify.
Heading orderModerate effort

Fix heading tags so they follow a logical, sequential order (H1 → H2 → H3…) without skipping levels anywhere on the page.

On Webflow

  1. Open your project in the Webflow Designer.
  2. Click on any Heading element on the canvas. In the Element Settings panel (the gear icon on the right), find the 'Tag' dropdown and change it to the correct heading level (H1–H6) that maintains sequential order.
  3. Do NOT change the heading level for visual reasons — instead, adjust typography in the Style panel (font size, weight, color) to make any heading level look the way you want.
  4. For CMS-driven pages, check your Collection Template page in the same way and fix heading tags in the template.
  5. Publish the site and run the axe DevTools extension to confirm there are no remaining heading-order violations.
Html has langQuick win

Add a valid `lang` attribute to the `<html>` element so browsers and assistive technologies know what language your page is written in.

On Webflow

  1. In the Webflow Designer, open Project Settings (the gear icon in the left toolbar or via the top menu).
  2. Go to the General tab. Find the 'Localization' or 'Language' field — set the Primary Language to your store's language. This controls the `lang` attribute on the `<html>` element sitewide.
  3. For Webflow Localization (multi-language sites), each locale's pages automatically receive the correct `lang` attribute based on the locale configuration under Project Settings → Localization.
  4. Publish the site, then verify via View Page Source that `<html lang="en">` (or your chosen language code) is present.
Html lang validQuick win

Set a valid BCP 47 language code on the `lang` attribute of your page's `<html>` element (e.g., `lang="en"`) so browsers, screen readers, and search engines correctly identify the page language.

On Webflow

  1. In the Webflow Designer, go to Project Settings (the gear icon in the top-left of the Designer, or via the Dashboard).
  2. Click the Localization tab (for multi-language sites) or the General tab.
  3. Under 'Localization / Language', set the primary locale/language for your site. Webflow will render the correct `lang` attribute on the `<html>` element automatically.
  4. For a single-language site without Localization enabled, Webflow uses your project's locale setting. Ensure it is set to your actual content language.
  5. Publish the site, then open the live page source and confirm `<html lang="en">` (or your code) is present.
Image altModerate effort

Add a descriptive `alt` attribute to every `<img>` element on your store so screen readers and search engines can understand what each image shows.

On Webflow

  1. **Designer — image elements:** Open the Webflow Designer → click on any Image element on the canvas → in the right-hand Settings panel (the gear icon), find the 'Alt Text' field → type your description, OR toggle 'Decorative' to mark it as decorative (this outputs `alt=""`).
  2. **CMS collection images:** Designer → CMS → Content → select a Collection → click a record → find the image field → add or edit the alt text sub-field. Alternatively, in the Designer, bind the alt text of an image element to a CMS text field via the Settings panel → 'Get alt text from' → choose a CMS field.
  3. **Ecommerce product images (Webflow Commerce):** Designer → Ecommerce → Products → edit a product → click the product image in the editor → enter alt text in the Settings panel, or bind it to a product field.
  4. **Bulk update via CMS:** Export your CMS collection as CSV (CMS → Collections → export) → fill in the alt text column → re-import.
  5. **Webflow Accessibility Checker:** Use the built-in Webflow Audit panel (the accessibility audit icon in the left toolbar) to surface all images missing alt text in your project.
Image redundant altModerate effort

Remove or empty the alt attribute on images whose caption or surrounding text already describes them, so screen readers don't announce the same information twice.

On Webflow

  1. In the Webflow Designer, click the image element → in the right-side Element Settings panel (the gear icon tab), find the 'Alt Text' field → clear it and tick 'Decorative (empty alt)' if the surrounding text already describes the image.
  2. For CMS-bound images (e.g., product or blog images): go to the CMS Collection settings → find the image field → ensure the alt text field binding is not pulling in the same text that appears in a linked text field on the same page.
  3. For background images (CSS): these have no alt attribute by nature and require no action for this rule.
  4. Publish and verify with axe DevTools in your browser.
Input button nameQuick win

Add a descriptive label to every input button so screen readers can announce what the button does.

On Webflow

  1. Open the Webflow Designer. In the Navigator panel, locate the Form Block that contains the submit button.
  2. Click the submit button element (usually a 'Submit Button' component within the Form Block).
  3. In the right-hand Settings panel (the gear icon), find the 'Value' field for the button and enter a descriptive label (e.g., 'Send Message', 'Subscribe', 'Check Out').
  4. If the button was added as a custom HTML Embed, switch to the Embed editor and update the `value` attribute directly in the HTML.
  5. Publish the site and validate with Chrome DevTools → Accessibility tab, or run axe DevTools browser extension to confirm the button now has an accessible name.
LabelModerate effort

Add a visible or programmatic label to every form input so assistive technologies can identify its purpose.

On Webflow

  1. Open your project in the Webflow Designer and click on the Form Block containing the unlabeled input.
  2. Select the individual Form Field element (Input, Textarea, or Select); in the right-hand Settings panel, ensure the 'Label' toggle is ON and the label text is descriptive (e.g., 'Email address', not just 'Email').
  3. Webflow automatically links the <label> to its input using for/id when the label is added via the Settings panel — do not delete the auto-generated id on the input.
  4. If you need a visually hidden label (design-only), add a custom 'sr-only' CSS class to the label element with CSS: position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap;
  5. For custom-embedded forms via HTML Embed components, manually add <label for="id"> markup inside the embed.
  6. Publish and test with axe DevTools or VoiceOver/NVDA.
Label title onlyModerate effort

Add a visible, persistent label to every form field so it is never labeled only by a tooltip (title) or hidden description (aria-describedby).

On Webflow

  1. Open your project in the Webflow Designer. Click on the Form Block or the individual Input element that is flagged.
  2. In the left panel (Navigator) or by clicking directly, select the Label element that should be associated with the input. Ensure its text content is descriptive (e.g., 'Email address') and it is visible (not set to `display: none` or `visibility: hidden` in the Style panel).
  3. To associate the label with the input: select the Label element → in the Settings panel (gear icon), set the 'For' attribute to match the input's ID. Then select the Input element → Settings → set its 'ID' to that same value.
  4. For inputs where a visible label is not desired (e.g., search bar), select the Input element → Settings → Custom Attributes → add `aria-label` with a descriptive value (e.g., `Search products`). Remove any `title`-only attribute used as a label.
  5. Publish and verify with axe DevTools or another browser accessibility extension.
Landmark banner is top levelModerate effort

Ensure your site's banner landmark (<header> or role="banner") sits at the top level of the page, not nested inside another landmark region.

On Webflow

  1. Open your project in the Webflow Designer. In the Navigator panel (left sidebar), locate the Navbar or Header element at the top of your page structure.
  2. Ensure the Navbar/Header element is a direct child of the Body node in the Navigator — it should not be nested inside a Section, Div Block, or any element that has a landmark role assigned.
  3. If it is nested, drag it in the Navigator panel to be directly under Body, above all other landmark-carrying elements.
  4. To check/change ARIA roles: select the element, open the Element Settings panel (D key), scroll to Custom Attributes, and ensure no conflicting `role` attribute is set on a wrapper around your header.
  5. Publish the site and verify with the axe DevTools browser extension.
Landmark complementary is top levelModerate effort

Move any `<aside>` element (or element with `role="complementary"`) so it is a direct child of `<body>`, not nested inside another landmark region like `<main>`, `<header>`, `<footer>`, or `<nav>`.

On Webflow

  1. Open your project in the Webflow Designer. In the Navigator panel (left sidebar), locate the element using an `<aside>` tag or with `role="complementary"` set.
  2. Check its position in the hierarchy. If it is a child of a `Main` element (the element with tag set to `<main>`), drag it in the Navigator so it becomes a sibling of `Main` — both sitting inside the `Body` element.
  3. To set or verify the HTML tag of an element, select it, open the Element Settings panel (D key), and confirm the Tag dropdown shows `aside` only for the complementary element and not for layout wrappers.
  4. To add an accessible label, select the `<aside>` element, go to Element Settings → Custom Attributes, and add `aria-label` with a descriptive value like `Related products`.
  5. Publish the site and re-run an axe audit in the browser to confirm the landmark is now top-level.
Landmark contentinfo is top levelModerate effort

Move your footer element (or any element with role="contentinfo") to the top level of the page so it is not nested inside another landmark region.

On Webflow

  1. Open your Webflow project in the Designer. In the Navigator panel (left sidebar), expand the page structure.
  2. Locate the Footer element (or any element you have tagged with the 'Footer' HTML tag or `role="contentinfo"`). It should appear at the root level of the page — a sibling of the Navbar, Main, and Section elements, NOT nested inside any of them.
  3. If the Footer element is nested inside a Main element or a Section/Container with a landmark role, drag it in the Navigator to be a direct child of the Body.
  4. If you added a custom attribute `role="contentinfo"` to a div that is inside another landmark, either remove that attribute or move the element out to the top level.
  5. Publish the site and validate with axe DevTools in your browser.
Landmark main is top levelModerate effort

Move the `<main>` element (or `role="main"`) so it is a direct child of `<body>` and not nested inside any other landmark element such as `<header>`, `<nav>`, `<aside>`, or `<footer>`.

On Webflow

  1. Open your project in the Webflow Designer.
  2. In the Navigator panel (left sidebar), inspect the page structure. Find the element tagged as `<main>` — Webflow lets you set the HTML tag of any element. Click the element, then in the right-hand Settings panel (the gear icon) confirm its Tag is set to `Main`.
  3. Ensure this `<main>` element is a direct child of `<body>` in the Navigator. It should be a sibling of your `<header>` (Navbar/Header section) and `<footer>` elements, not nested inside either.
  4. If `<main>` is inside a `<header>` or other landmark, drag it in the Navigator to sit at the body level alongside those elements.
  5. Publish the site and verify with axe DevTools or WAVE browser extension.
Landmark no duplicate bannerModerate effort

Ensure your page has only one banner landmark (a single `<header>` element or `role="banner"`) so assistive technologies can navigate your site correctly.

On Webflow

  1. Open your project in the Webflow Designer. In the Navigator panel (left sidebar), expand your page structure.
  2. Identify all elements with a 'Header' tag (shown as 'Header' in the Navigator with an HTML tag of <header>).
  3. Only ONE top-level Header element should exist. Click any additional Header elements → in the right-side Settings panel, change the element tag from 'Header' to 'Div Block' (this changes <header> to <div> in the output).
  4. For any element with a custom attribute role="banner" that is NOT the main site header, select the element → Settings → Custom Attributes → delete the role="banner" attribute.
  5. Check if any Symbols (components) contain a <header> tag that gets repeated across pages — edit the Symbol to use a <div> if it is not the true site header.
  6. Publish and verify with axe DevTools or WAVE.
Landmark no duplicate contentinfoModerate effort

Remove duplicate `<footer>` elements or `role="contentinfo"` landmarks so your page has exactly one, site-wide footer region.

On Webflow

  1. Open your project in the Webflow Designer. In the Navigator panel (left sidebar), expand your page structure and look for any elements with the tag `Footer` (Webflow renders these as `<footer>` in HTML).
  2. Your site should have exactly one Footer element — typically inside your global symbol or on the page canvas. If you see two Footer-tagged elements on the same page (one in a Symbol and one added manually to the page), delete the duplicate.
  3. To change the HTML tag of an element: select the element → go to the Element Settings panel (D key) → under 'Tag', change `footer` to `div` for the non-primary one.
  4. Check your global Footer Symbol (if used): go to Assets panel → Symbols → open Footer Symbol. Ensure it contains only one `<footer>` element inside it.
  5. If any Embed code component (</> icon) contains `<footer>` HTML, edit that embed and replace the tag with `<div>`.
  6. Publish and verify with the axe extension.
Landmark no duplicate mainModerate effort

Ensure each page contains exactly one `<main>` landmark element (or one element with `role="main"`) so screen-reader users can navigate directly to the page's primary content.

On Webflow

  1. Open your project in the Webflow Designer. In the Navigator panel (left sidebar), inspect the page structure for any element whose tag is set to '<main>'.
  2. Click each suspect container element, open the Element Settings panel (right sidebar, gear icon), and check the 'Tag' dropdown. Only ONE element across the entire page should be set to 'Main'. Change any additional ones to 'Section', 'Div Block', or 'Article' as appropriate.
  3. Check any Symbols or Components used on the page — open each Symbol and verify it does not internally use a '<main>' tag.
  4. If third-party embed code (via Embed components) injects '<main>', edit the embed HTML and replace it with '<div>' or '<section>'.
  5. Publish the site and re-test with the axe DevTools browser extension.
Landmark one mainQuick win

Add a single `<main>` landmark element (or `role="main"`) to every page so that screen-reader users and assistive technologies can skip directly to the primary content.

On Webflow

  1. Open your project in the Webflow Designer.
  2. In the Navigator panel, find the top-level `<div>` or `<Section>` that contains your page-unique content (below the Navbar component, above the Footer component).
  3. Click the element, then in the right-hand Settings panel (the gear icon) change the HTML Tag from `div` to `main`.
  4. Set the element ID to `main-content` (Settings panel → ID field) so a skip link can target it.
  5. Add a Text Link element as the very first child of `<body>` (before the Navbar): set its URL to `#main-content`, give it a class `skip-link`, and use Webflow's visibility settings (display: none / show on focus) to style it as a visually-hidden skip link.
  6. Publish and confirm with the axe browser extension.
Landmark uniqueModerate effort

Add a unique aria-label (or aria-labelledby) to every repeated landmark role so assistive technologies can distinguish between them.

On Webflow

  1. Open your project in the Webflow Designer and select the Navbar or Nav Menu component that is duplicated.
  2. With the element selected, open the Element Settings panel (the gear icon on the right) and scroll to the Custom Attributes section.
  3. Click the '+' button, enter 'aria-label' as the Name and your unique label (e.g. 'Primary navigation') as the Value.
  4. Select each additional instance of the same landmark type (e.g. footer nav) and repeat, using a different label (e.g. 'Footer navigation').
  5. Publish the site and re-run your accessibility scanner or use Webflow's built-in Audit panel (the eye icon in the left toolbar) to confirm the landmark-unique issue is resolved.
Link in text blockModerate effort

Make inline links visually distinguishable from surrounding body text by ensuring at least 3:1 color contrast between the link color and the non-link text color, or by adding a non-color visual cue (such as underline) to every link.

On Webflow

  1. Open your project in the Webflow Designer.
  2. In the left panel, go to Navigator or click directly on a link element inside a Rich Text block or paragraph.
  3. On the right-side Styles panel, select the `All Links` or `a` tag-level selector (choose 'Tag' from the selector type dropdown).
  4. Update the Color property to a value with ≥3:1 contrast against body text color, and/or set Text Decoration to 'Underline'.
  5. For Rich Text link styles specifically, select a Rich Text element → go to its styles → click the '…' inside the Rich Text settings to style nested elements including links.
  6. Publish and verify on a staging/live page using the axe DevTools extension.
Link nameModerate effort

Add a descriptive, screen-reader-accessible label to every link on your store so assistive technologies can announce where each link leads.

On Webflow

  1. Open the Webflow Designer and select the unnamed link element in the Navigator panel.
  2. In the right-hand Settings panel (gear icon), find the 'Aria Label' field and enter a descriptive label (e.g. 'View shopping cart').
  3. For linked images, select the image element inside the link, open its Settings panel, and fill in the 'Alt Text' field.
  4. For CMS-driven links (e.g. product cards), open the Collection List item, select the link wrapper, and bind its Aria Label to a CMS field (e.g. the product name field) using dynamic binding.
  5. Publish the site and verify with the axe DevTools browser extension in the published URL.
ListModerate effort

Fix all HTML list elements so that `<ul>` and `<ol>` contain only valid `<li>` children, and `<li>` elements appear only inside a proper list container, ensuring correct semantic list structure throughout your store.

On Webflow

  1. Open the Webflow Designer for your project.
  2. In the Navigator panel (left sidebar), locate the List element that is flagged. Webflow has dedicated 'List' and 'List Item' elements that enforce correct structure when used properly.
  3. If you have placed a Div Block directly inside a List element (instead of inside a List Item), select the Div Block in the Navigator and drag it inside a 'List Item' element, or wrap it: right-click the element → Wrap in → List Item.
  4. Never place a List Item element outside a List container in the Navigator — if you find one, drag it inside the appropriate List.
  5. For any custom HTML added via an Embed element, click the Embed block → open the code editor → inspect and fix any malformed list HTML.
  6. Publish the site and re-run the accessibility audit via axe DevTools to confirm the issue is resolved.
ListitemQuick win

Wrap every `<li>` element in a proper `<ul>` or `<ol>` parent so screen readers and browsers can correctly identify and announce list structure.

On Webflow

  1. Open the Webflow Designer for your project.
  2. In the Navigator panel (left sidebar), find the `List Item` element that is not nested inside a `List` element.
  3. Select the orphaned List Item, then in the Navigator drag it inside an existing List element, OR add a new List element (Add Elements panel → List) and nest the List Item inside it.
  4. Alternatively, switch to the page's Embed element (if the `<li>` is in a custom HTML Embed block), click the </> icon to open the HTML editor, and add the `<ul>` wrapper manually.
  5. Publish the site and use the axe browser extension to confirm the fix.
Meta refreshQuick win

Remove or disable any `<meta http-equiv="refresh">` tag that automatically redirects or reloads the page in under 20 hours.

On Webflow

  1. In the Webflow Designer, open your Project Settings (the gear icon or Site Settings in the dashboard).
  2. Go to the Custom Code tab and check the 'Head Code' field for any `<meta http-equiv="refresh" ...>` tag — delete it if present, then Save.
  3. Also select individual pages in the Pages panel → click the settings gear next to each page → check the 'Custom Code' → 'Head Code' field for that page.
  4. If the tag was added to a component or embed element, select that element on the canvas, open its settings panel, and remove it from the HTML Embed code.
  5. For URL redirects, go to Project Settings → Hosting → 301 Redirects and add a proper redirect there instead.
Meta viewportQuick win

Remove `user-scalable=no` (and any `maximum-scale` value below 5) from your site's `<meta name="viewport">` tag so visitors can pinch-to-zoom on mobile devices.

On Webflow

  1. In the Webflow Designer, open your Project Settings (gear icon at the top of the left panel or via the Dashboard).
  2. Go to the Custom Code tab.
  3. In the 'Head Code' field, look for any `<meta name="viewport">` tag and remove `user-scalable=no` / fix `maximum-scale`.
  4. Webflow's own injected viewport tag is compliant by default, so this fix usually only applies if a developer manually added a custom tag.
  5. Publish the site and test on a mobile device.
Meta viewport largeQuick win

Remove or raise the `maximum-scale` value in your site's `<meta name="viewport">` tag so mobile users can pinch-to-zoom freely.

On Webflow

  1. In the Webflow Designer, open Project Settings (gear icon, top-left).
  2. Go to the Custom Code tab.
  3. In the 'Head Code' field, add: `<meta name="viewport" content="width=device-width, initial-scale=1.0">`.
  4. Click Save Changes, then Publish your site.
  5. Inspect the rendered source on mobile to confirm no `maximum-scale` restriction remains.
Nested interactiveModerate effort

Remove or restructure focusable elements nested inside interactive controls so that no interactive element contains another focusable child.

On Webflow

  1. Open your project in the Webflow Designer.
  2. In the Navigator panel (left sidebar), locate the offending component — typically a Collection List Item, a Link Block, or a Card component that contains a Button or another Link Block inside it.
  3. Select the outer interactive wrapper (e.g. a Link Block). In the Settings panel (right sidebar) check its tag/element type.
  4. Change the outer wrapper from a Link Block to a Div Block: right-click the element in the Navigator → 'Change tag' is not directly available, so instead: (a) add a new Div Block at the same level, (b) move all children into it, (c) delete the old Link Block, then (d) add the product title link as a separate Link element inside the new Div.
  5. Ensure the Add to Cart button (from the Webflow Ecommerce Add to Cart component) and the title Link are direct children of the new Div, not nested inside each other.
  6. Publish and test keyboard tab order in a browser.
Object altQuick win

Add a descriptive text alternative to every `<object>` element so screen readers can convey its content to users who cannot see it.

On Webflow

  1. In the Webflow Designer, select the Embed element that contains your `<object>` tag (or add one via Add Panel → Components → Embed).
  2. Click the Embed element to open its settings and view/edit the raw HTML code field.
  3. Add `aria-label="Descriptive text here"` to the `<object>` opening tag in that code field.
  4. Alternatively, if the `<object>` is part of a CMS Rich Text field, edit the field content in the CMS collection and switch to HTML view to add the attribute.
  5. Publish the site and verify using axe DevTools in the browser.
Page has heading oneModerate effort

Add a single, descriptive `<h1>` heading to every page so screen readers and search engines can identify the page's main topic.

On Webflow

  1. Open your project in the Webflow Designer and navigate to the page.
  2. In the Navigator or on the canvas, find the main title element. Click it and check the Element panel on the left — if it shows 'Heading' with a tag of H2 or lower, change the tag to **H1** using the tag dropdown in the Settings panel (the gear icon).
  3. If no `<h1>` exists, press 'A' to open Add Elements, drag a **Heading** element onto the canvas, set its tag to H1, and type the page title.
  4. For **Webflow Commerce** product and category pages: open the product/category template, find the product name or category name text block, and confirm its heading level is H1 in the Settings panel.
  5. Publish the project and inspect the live page with browser DevTools to confirm `<h1>` is present.
Presentation role conflictModerate effort

Remove conflicting ARIA attributes and tabindex from elements that are marked as presentational (role="presentation" or role="none"), so screen readers consistently ignore them.

On Webflow

  1. Open your Webflow Designer and select the element flagged with the conflict.
  2. In the right-hand panel, open the Element Settings tab (the gear icon) and scroll to the Custom Attributes section.
  3. Review every attribute listed: if role is set to 'presentation' or 'none' AND an aria-* attribute or tabindex is also present, remove the conflicting one(s) following the decision logic in the generic steps.
  4. If the element should be purely decorative, delete all ARIA attributes and tabindex, keeping only role="presentation" (or remove the role entirely for non-semantic tags like div/span).
  5. Publish the site and run an axe DevTools scan to confirm the fix.
RegionModerate effort

Wrap all visible page content inside HTML landmark elements (such as `<main>`, `<nav>`, `<header>`, `<footer>`, or ARIA `role` attributes) so screen-reader users can navigate your store efficiently.

On Webflow

  1. Open your project in the Webflow Designer. In the Navigator panel (left sidebar), locate the outermost structure of your page.
  2. Select the site header/navbar element, open its Settings panel (right sidebar), and change its HTML tag from `Div` to `Header` using the Tag dropdown — Webflow will output `<header>` which browsers map to `role="banner"` automatically.
  3. Select the main content wrapper `Div`, change its tag to `Main` — this outputs `<main>` with the implicit `role="main"`.
  4. Select the footer element and change its tag to `Footer` (outputs `<footer>` with implicit `role="contentinfo"`).
  5. For any standalone content sections (e.g. a promo banner `Div` outside the main wrapper), select it, change its tag to `Section`, then open the Element Settings panel and add a custom attribute: Name = `aria-label`, Value = `[Section purpose, e.g. Promotional Banner]`. This gives it an explicit landmark.
  6. Publish the site, then run axe DevTools on the live or staging URL to confirm all content is inside landmarks.
Role img altQuick win

Add an accessible text label (aria-label) to every element that has role="img" so screen readers can announce what the image conveys.

On Webflow

  1. Open your project in the Webflow Designer and select the element flagged (e.g., an SVG embed, Lottie animation div, or icon element).
  2. In the right-hand panel, open the Element Settings tab (the gear icon).
  3. Scroll to the Accessibility section and enter your label in the 'Custom attributes' area: add attribute name aria-label with the descriptive value, e.g., '4 out of 5 stars'.
  4. For purely decorative elements, add aria-hidden with value true instead.
  5. For SVG elements embedded via an Embed component, click the embed, open the code, and manually add aria-label="[text]" to the <svg> tag.
  6. Publish the site and validate with axe DevTools.
Scrollable region focusableQuick win

Make every scrollable region on your store reachable and operable by keyboard by adding tabindex="0" (or placing focusable content inside it) so users who cannot use a mouse can scroll it.

On Webflow

  1. Open your project in the Webflow Designer and select the scrollable Div Block or Section.
  2. In the right-hand Settings panel (the gear icon), find the 'Custom Attributes' section at the bottom.
  3. Click the + button and add attribute Name: tabindex, Value: 0.
  4. Add a second attribute: Name: aria-label, Value: Product description (or appropriate label).
  5. Open the Style panel and add a :focus state to the element with an outline (e.g. 2px solid #005fcc).
  6. Publish the site and test keyboard navigation to confirm Tab reaches the element.
Select nameModerate effort

Add a descriptive, programmatically associated label to every `<select>` dropdown element on the site so assistive technologies can announce its purpose to users.

On Webflow

  1. Open the Webflow Designer. Click the Select element (dropdown) on the canvas to select it.
  2. In the left-hand Element Settings panel (the gear icon), find the 'Label' field — type your descriptive label text here. Webflow will render a visible <label> element linked to the select.
  3. If you want a visible label on the canvas, add a Form Label element from the Add panel (A → Form elements → Label), place it above the Select, then in the Label settings set 'For' to the Select's element ID.
  4. To use aria-label instead of a visible label: select the Select element → go to Element Settings → Custom Attributes → click '+' → Name: aria-label, Value: 'Your descriptive text'.
  5. Publish the site and verify with axe DevTools or VoiceOver.
Skip linkQuick win

Add a valid, matching target ID to every skip-navigation link so keyboard and assistive-technology users can bypass repeated header content and jump directly to the main content area.

On Webflow

  1. Open your project in the Webflow Designer. In the left panel, click the Navigator and find the very first element inside the <body> — this is where the skip link must live.
  2. Add a Link Block or Text Link as the absolute first child of Body. Set its href to #main-wrapper (or any id you choose). Give it a custom class skip-link and apply the visually-hidden-until-focus CSS in the Style panel (position: absolute; top: -9999px; then add an interaction or :focus state to bring it on-screen).
  3. Select the Section or Div that wraps your main page content (below the Navbar component). In the element Settings panel (D key), add a custom attribute: Name = id, Value = main-wrapper. Also add tabindex = -1.
  4. Publish and test: Tab once on the live site should reveal the skip link; pressing Enter should scroll/focus to the main content section.
  5. For Webflow Ecommerce pages (product, collection, cart), repeat the id assignment on the main content wrapper in each page template.
Svg img altModerate effort

Add a meaningful text alternative to every SVG image so screen readers can describe it to visually impaired shoppers.

On Webflow

  1. In the Webflow Designer, select the SVG element on the canvas.
  2. In the Element Settings panel (the gear icon on the right), find the 'Alt Text' field for SVG Image elements — fill in a descriptive label; Webflow will render this as an accessible attribute.
  3. For SVGs embedded as HTML Embed components (</> icon), click the embed → open the code editor → manually add `role='img'`, `aria-labelledby='UNIQUE-ID'`, and `<title id='UNIQUE-ID'>Descriptive text</title>` as the first child of the `<svg>`.
  4. For decorative SVGs, set Alt Text to empty ('') or, in an HTML Embed, add `aria-hidden='true'` and `focusable='false'` to the `<svg>` tag.
  5. Publish and validate with the axe browser extension.
TabindexModerate effort

Remove all positive tabindex values (tabindex="1" or higher) from your store's HTML elements, replacing them with tabindex="0" or relying on natural document order to control keyboard focus.

On Webflow

  1. Open the Webflow Designer for your project.
  2. Select the element that has the positive tabindex. In the right-hand Settings panel (gear icon), scroll to the 'Accessibility' section — Webflow exposes a 'Tab Index' field here. Clear the positive value or set it to 0.
  3. For elements where the tabindex was added via custom attributes: in the Settings panel → 'Custom Attributes' section, find the tabindex attribute row and update its value.
  4. If the element is inside an Embed widget (</> icon), click 'Edit' on the embed and correct the raw HTML.
  5. Publish the project and verify by tabbing through the published page.
Valid langModerate effort

Add a valid BCP 47 language code to every `lang` attribute on your pages so assistive technologies can read content in the correct language.

On Webflow

  1. In the Webflow Designer, go to Project Settings (the gear icon) → Localization (or General) and set the primary locale/language. Webflow uses this to populate `<html lang>`.
  2. Alternatively, open Project Settings → Custom Code → add a `<script>` in Head Code that sets `document.documentElement.lang = 'en';` only if Webflow does not expose a direct language field for your plan — but prefer the Localization setting.
  3. For Webflow Localization (paid feature): Settings → Localization → add/edit each locale and ensure its language code is a valid BCP 47 tag. Webflow sets `lang` per locale automatically.
  4. For any Embed components (HTML Embed blocks) in the canvas that contain a `lang` attribute, click the block, open the HTML editor, and correct the value.
  5. Publish the site and verify with the axe browser extension.

Security (OWASP) · 23 fixes

Dmarc policy noneModerate effort

Strengthen your DMARC policy from p=none (monitor-only) to p=quarantine, then p=reject, to actively block email spoofing of your domain.

On Webflow

  1. Webflow does not host DNS unless you purchased your domain through Webflow. If your domain was purchased via Webflow, go to Webflow Dashboard > Project Settings > Hosting > Custom Domain > DNS Settings (or manage via the Webflow DNS panel).
  2. If your domain is at an external registrar, log in there and go to DNS management.
  3. Find the TXT record with Name/Host _dmarc and edit it.
  4. Change p=none to p=quarantine, save, and propagate.
  5. Webflow itself does not send email on your behalf; ensure any connected tools (Mailchimp, Klaviyo form integrations, etc.) are in your SPF and have DKIM set up.
  6. After a clean monitoring window, return and change p=quarantine to p=reject.
Hsts disabledQuick win

Enable HTTP Strict-Transport-Security (HSTS) by setting a max-age of at least 31536000 seconds (one year) so browsers always use HTTPS when visiting your store.

On Webflow

  1. Webflow automatically provisions SSL and sets HSTS headers for all sites published to Webflow Hosting — no manual action is needed for webflow.io or connected custom domains.
  2. Ensure your site is published to Webflow Hosting (not self-hosted export): Webflow Designer → Publish → Webflow subdomain or your custom domain.
  3. For custom domains, go to Webflow Dashboard → Project Settings → Publishing → Custom Domain, confirm SSL is active (green padlock shown).
  4. If you export and self-host Webflow code on your own server, add the HSTS header in your Nginx or Apache config as described in the WooCommerce server steps above.
Hsts max age too shortQuick win

Increase your HSTS max-age to at least 31536000 (one year) so browsers enforce HTTPS-only connections for a meaningful period.

On Webflow

  1. Webflow hosted sites enforce HTTPS but do not expose a UI control for custom HTTP security headers on standard hosting plans.
  2. For Webflow Enterprise: contact your Webflow account manager to request custom header configuration including Strict-Transport-Security: max-age=31536000; includeSubDomains.
  3. For sites published to a custom host (e.g. self-hosted export or via Cloudflare): in Cloudflare go to your domain → Rules → Transform Rules → Response Header Modification. Add a 'Set' rule for header name 'Strict-Transport-Security' with value 'max-age=31536000; includeSubDomains'.
  4. Alternatively, in Cloudflare's SSL/TLS → Edge Certificates section, enable HTTP Strict Transport Security (HSTS) and set Max Age to 12 months (31536000).
  5. Verify at securityheaders.com.
Https not availableQuick win

Enable HTTPS by installing a valid SSL/TLS certificate and redirecting all HTTP traffic to the secure HTTPS version of your store.

On Webflow

  1. Webflow automatically provisions a free SSL certificate (via Fastly/Let's Encrypt) for all published sites on a paid hosting plan.
  2. In your Webflow Dashboard, open the project and go to Publishing → Custom Domains.
  3. Confirm the SSL badge next to your domain shows 'SSL Active'. If it shows 'Pending', wait up to 24 hours for DNS propagation, then retry.
  4. Webflow automatically redirects HTTP to HTTPS for all hosted sites — no additional configuration is needed.
  5. In Project Settings → Hosting, ensure 'Enable SSL' is toggled on (it is on by default).
Info disclosure serverQuick win

Remove or obscure the Server HTTP response header so your web server software name and version are no longer exposed to the public internet.

On Webflow

  1. Webflow hosting is fully managed — merchants cannot access the underlying server configuration.
  2. Webflow serves sites through its own CDN (powered by Fastly) and does not expose exploitable server version strings by design.
  3. If you use a custom domain with Cloudflare in front of Webflow: Cloudflare dashboard → your domain → Rules → Transform Rules → Modify Response Header → add a Remove rule for the `Server` header.
  4. For Webflow Enterprise with a custom reverse proxy, work with your infrastructure team to strip the `Server` header at the proxy layer.
Info disclosure x powered byQuick win

Remove or mask the X-Powered-By HTTP response header to stop advertising your server technology stack to attackers.

On Webflow

  1. Webflow-hosted sites run on Webflow's managed CDN; site owners cannot configure raw HTTP response headers from the Webflow Designer or Editor.
  2. If you use Webflow's Logic or connect external services/webhooks, ensure those external endpoints suppress X-Powered-By at their own server or CDN layer.
  3. For sites exported from Webflow and self-hosted: configure header removal in your own web server (Nginx/Apache) or CDN (Cloudflare) as described in the generic steps.
Insecure cookieModerate effort

Set the HttpOnly, Secure, and SameSite=Strict flags on every session and CSRF cookie your store sets so they cannot be stolen by malicious scripts or sent over unencrypted connections.

On Webflow

  1. Webflow-managed cookies (including Webflow Memberships session cookies) are set server-side by Webflow. Ensure SSL is enabled: Project Settings → Hosting → SSL and publish to a custom domain with HTTPS.
  2. For the Webflow Memberships feature: session cookies are controlled by Webflow. Ensure you are on the latest Webflow plan and Memberships version; report missing flags via Webflow Support.
  3. For custom cookies set in Webflow custom code (Site Settings → Custom Code → Head/Footer, or Embed elements): audit all `document.cookie =` assignments; append `; Secure; SameSite=Strict`. Move any HttpOnly cookie creation to a backend service (e.g., a Cloudflare Worker or your own API) since JS cannot set HttpOnly.
  4. If using Webflow's Logic or integrations (e.g., Zapier, Make) that set cookies on your domain: review each integration for cookie security settings and update to latest versions.
  5. Use browser DevTools → Application → Cookies after publishing to verify all cookies carry the correct flags.
Missing content security policyModerate effort

Add a Content-Security-Policy (CSP) response header to every page so browsers block unauthorized scripts, styles, and resources from loading.

On Webflow

  1. Webflow hosted sites do not allow direct HTTP header configuration through the Webflow Designer or dashboard for standard plans.
  2. The recommended method is to proxy through Cloudflare: point your domain to Cloudflare, then go to Cloudflare Dashboard → Rules → Transform Rules → Modify Response Headers → Create Rule → set `Content-Security-Policy` to your policy string.
  3. If you export your Webflow site and self-host (e.g., on Netlify or Vercel): for Netlify, add a `[[headers]]` block in `netlify.toml`; for Vercel, add a `headers` array in `vercel.json` with your CSP value.
  4. Webflow sites commonly load resources from `uploads-ssl.webflow.com`, `fonts.googleapis.com`, and any integrations you've added — include these in your `script-src` and `font-src` directives.
Missing dmarcQuick win

Add a DMARC DNS TXT record at _dmarc.yourdomain.com to protect your domain from email spoofing and phishing.

On Webflow

  1. In your Webflow dashboard, open Project Settings → Publishing → Custom Domain.
  2. If Webflow manages your DNS (domain purchased via Webflow): click 'Edit DNS' next to your domain. Under DNS Records, click 'Add record', choose TXT, set Name = '_dmarc', Value = v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com. Save.
  3. If your domain is with an external registrar: log in there and add the TXT record (Name = '_dmarc', Type = TXT, Value = your DMARC string).
  4. Webflow does not send transactional ecommerce emails natively beyond basic order notifications — most Webflow Commerce stores use an ESP. Ensure SPF and DKIM are configured for your domain in your ESP before escalating DMARC policy to p=quarantine or p=reject.
  5. Verify the record has propagated using MXToolbox DMARC check (search 'MXToolbox DMARC lookup') after 24–48 hours.
Missing permissions policyQuick win

Add a Permissions-Policy HTTP response header to explicitly restrict which browser features (camera, microphone, geolocation, etc.) your store's pages are allowed to use.

On Webflow

  1. Webflow does not expose HTTP header configuration natively in its hosting dashboard for standard plans.
  2. For Webflow Enterprise, contact support or use the site settings to configure custom headers if available in your plan.
  3. For all other plans, use Cloudflare as a proxy: add your Webflow site's domain to Cloudflare → Rules → Transform Rules → Modify Response Headers → Add header 'Permissions-Policy' with value 'camera=(), microphone=(), geolocation=(), payment=(), usb=()'.
  4. Alternatively, in Webflow Designer → Project Settings → Custom Code → Head Code, add: <meta http-equiv='Permissions-Policy' content='camera=(), microphone=(), geolocation=()'> as a partial browser hint.
  5. Verify with Chrome DevTools → Network → Response Headers.
Missing referrer policyQuick win

Add a `Referrer-Policy: strict-origin-when-cross-origin` HTTP response header to every page so browsers control what referrer information is sent with requests.

On Webflow

  1. Webflow does not support custom HTTP response headers natively.
  2. Add the meta tag via the Project Settings: open your project → Project Settings → SEO tab → Extra `<head>` tags → paste `<meta name="referrer" content="strict-origin-when-cross-origin">` → Save and republish.
  3. For a true HTTP header, use Cloudflare (proxy your Webflow-published domain) → Rules → Transform Rules → Modify Response Header → add `Referrer-Policy: strict-origin-when-cross-origin`.
  4. Verify via browser DevTools or securityheaders.com after publishing.
Missing spfQuick win

Add a DNS TXT record containing a valid SPF policy to your domain so email servers can verify that messages sent from your domain are legitimate.

On Webflow

  1. Webflow hosts your site but does not send transactional ecommerce email directly — outbound order emails typically go through a connected ESP or Webflow's built-in system.
  2. DNS for your Webflow site is managed wherever your domain is registered (e.g. Namecheap, GoDaddy, Cloudflare) or via Webflow's Domain settings if you purchased the domain there.
  3. In Webflow Designer/Dashboard: go to Project Settings → Publishing → Custom Domain → 'Edit DNS settings' (if Webflow-registered domain) OR log in to your external DNS provider.
  4. Add a TXT record: Host = @, TTL = 3600, Value = your SPF string covering your email-sending services.
  5. For Webflow Ecommerce transactional emails, check your Webflow project's Ecommerce → Settings → Emails section to see the sending address and which service delivers it, then include that provider's SPF tag.
  6. Verify propagation using an SPF checker.
Missing strict transport securityQuick win

Add an HTTP Strict-Transport-Security (HSTS) response header with at least `max-age=31536000; includeSubDomains` to every HTTPS response your store sends.

On Webflow

  1. Webflow automatically provisions SSL certificates and sends HSTS headers for all sites hosted on Webflow's infrastructure (*.webflow.io and custom domains).
  2. In your Webflow Dashboard → go to your Project Settings → Publishing → Custom Domain → ensure the domain shows 'SSL Active'.
  3. Webflow sends HSTS by default once SSL is active — no code change is needed in the Webflow Designer or CMS.
  4. If you are using a custom reverse proxy or Cloudflare in front of Webflow, configure HSTS there: Cloudflare → SSL/TLS → Edge Certificates → HSTS section → Enable, set max-age to 31536000, enable includeSubDomains.
  5. Verify in DevTools → Network → document response headers for `strict-transport-security`.
Missing x content type optionsQuick win

Add the `X-Content-Type-Options: nosniff` HTTP response header to every page of your store so browsers never guess at file types.

On Webflow

  1. Webflow does not currently provide a native UI for setting custom HTTP response headers on its hosted sites.
  2. The recommended approach is to proxy your Webflow site through Cloudflare (free plan): add your site to Cloudflare, then go to Rules → Transform Rules → Modify Response Header → Create Rule, set Header Name = X-Content-Type-Options, Value = nosniff, and apply it to all requests.
  3. Alternatively, use Cloudflare Workers or another reverse proxy/CDN that supports custom response headers.
  4. For Webflow sites exported and self-hosted, add the header in your hosting environment's server config (Apache .htaccess or Nginx config).
  5. Verify using browser dev-tools after Cloudflare or server-side changes are deployed.
Missing x frame optionsQuick win

Add an X-Frame-Options HTTP response header set to DENY or SAMEORIGIN to prevent your store's pages from being embedded in iframes on other websites.

On Webflow

  1. In your Webflow project, go to Project Settings → Security (or the 'Hosting' tab, depending on your plan) — Webflow allows you to add custom HTTP response headers for sites on the paid hosting plans.
  2. Under 'Custom Response Headers', click Add Header, enter Name: X-Frame-Options, Value: SAMEORIGIN, and save.
  3. Publish your site for the change to take effect.
  4. Verify via DevTools → Network → Response Headers on any published page.
  5. If you host Webflow via a custom server/export, add the header in your Nginx or Apache config as described in the WooCommerce steps above.
Passive scan onlyModerate effort

Complement passive security scans with active Dynamic Application Security Testing (DAST) against a staging copy of your store before each release.

On Webflow

  1. Webflow is managed SaaS; you cannot run DAST against Webflow's hosting infrastructure. Direct active scanning is not permitted.
  2. Focus DAST on any custom code added via the Webflow Designer's Embed elements or Page Settings → Custom Code sections — extract this code and review it manually or run it in an isolated test harness.
  3. If your Webflow site connects to external APIs (e.g. a custom backend, Xano, or Make/Zapier flows), deploy a staging copy of that backend and scan it with OWASP ZAP.
  4. Audit third-party scripts loaded by your Webflow site (Designer → Pages → Page Settings → Before/After </body>) — remove any scripts not actively needed, as third-party JS is a primary attack vector.
  5. Ensure Webflow's built-in SSL is active (Webflow Dashboard → Hosting → SSL) and that form submissions do not expose sensitive data in Webflow's form notification emails.
  6. For ecommerce stores handling significant transaction volume, evaluate exporting to a self-hosted environment (Webflow export + custom hosting) where full DAST is possible.
Ssl cert expiring soonQuick win

Renew your SSL/TLS certificate before it expires to keep your store secure, trusted, and visible in search results.

On Webflow

  1. Webflow automatically provisions and renews SSL via Fastly/Let's Encrypt for all published sites on custom domains — no manual renewal required.
  2. To check: go to Webflow Designer → Project Settings → Hosting → Custom Domains. A green lock icon next to your domain confirms SSL is active.
  3. If SSL is not provisioning: confirm your domain's DNS A record and CNAME are pointing to Webflow's servers (values are shown in Project Settings → Hosting → DNS Settings).
  4. To force re-provisioning after a DNS fix, remove the custom domain from Webflow and re-add it.
  5. Enable 'Redirect HTTP to HTTPS' under Project Settings → Hosting → Security to ensure all traffic is encrypted.
Ssl cert invalidModerate effort

Install a valid SSL/TLS certificate that exactly matches your store's domain name, so browsers trust your site and customer data is encrypted in transit.

On Webflow

  1. Webflow automatically provisions SSL certificates for all published sites, including custom domains, via Cloudflare.
  2. Go to your Webflow Dashboard → select your project → Publishing → Custom Domains.
  3. If the domain shows an SSL error, verify the DNS records at your registrar match exactly what Webflow specifies (an A record and a CNAME, or Webflow-provided nameservers).
  4. Once DNS is correctly configured, click 'Publish' or 'Re-verify SSL' in the Webflow Publishing panel. Webflow/Cloudflare will auto-provision the certificate (usually within minutes).
  5. If you transferred your domain to Webflow's registrar, SSL is managed entirely by Webflow and no manual action is needed after transfer.
Ssl errorModerate effort

Replace or reissue your SSL/TLS certificate so it is valid for the exact domain name your store uses, eliminating the hostname mismatch error.

On Webflow

  1. Webflow automatically provisions SSL certificates for published sites on webflow.io subdomains and for custom domains added through the Webflow dashboard.
  2. Go to: Webflow Designer → Site Settings (gear icon) → Publishing → Custom Domains.
  3. Add or re-verify your custom domain. Webflow will display the required DNS records (A record and CNAME) — ensure these are set at your domain registrar.
  4. Click 'Publish' after DNS records are confirmed; Webflow will provision an SSL certificate automatically.
  5. If the certificate shows a mismatch, remove the custom domain from Webflow, confirm DNS has fully propagated (use a DNS checker), then re-add the domain.
  6. Webflow does not support uploading custom SSL certificates — certificates are fully managed by the platform.
Ssl not accessibleModerate effort

Enable HTTPS on your store by opening port 443 and installing a valid SSL/TLS certificate so every page is served over a secure connection.

On Webflow

  1. Webflow automatically provisions free SSL certificates and manages port 443 for all sites hosted on Webflow's infrastructure.
  2. In Webflow Designer, go to Project Settings → Hosting.
  3. Ensure your custom domain is added and DNS is configured as instructed (A record or CNAME per Webflow's dashboard guidance). Webflow will auto-provision the certificate.
  4. Confirm 'HTTPS Redirect' is enabled in Project Settings → Hosting → Custom Domain section — this ensures port-80 traffic redirects to 443.
  5. If you see an SSL error, remove and re-add the custom domain in Project Settings → Hosting to trigger re-provisioning.
  6. For Webflow sites exported and hosted on your own server, open port 443 in your server firewall and install a TLS certificate (see generic steps).
Weak spfQuick win

Add a hard-fail (-all) or soft-fail (~all) mechanism to your SPF DNS record so that mail servers are explicitly told to reject or flag email from senders not listed in your record.

On Webflow

  1. Webflow hosts sites but does not manage email sending infrastructure, so SPF must be set at your DNS provider.
  2. If your DNS is managed inside Webflow: go to Webflow Dashboard → your project → Publishing → Custom Domain → DNS Settings. Add or edit the TXT record for @ with v=spf1 ... -all.
  3. If you use an external DNS provider (Cloudflare, Route 53, GoDaddy), log in there and edit the TXT record for your root domain.
  4. Include any transactional email services you use (e.g. Postmark, SendGrid) before closing with -all.
X content type options weakQuick win

Set the X-Content-Type-Options response header to exactly `nosniff` (once, not duplicated) on every page and asset your store serves.

On Webflow

  1. Webflow automatically sends `X-Content-Type-Options: nosniff` on all hosted projects.
  2. If a duplicate is found, check whether you have Cloudflare or another reverse proxy on your custom domain: Cloudflare Dashboard → Rules → Transform Rules → Modify Response Headers — delete any rule that also sets `X-Content-Type-Options`.
  3. For Webflow sites exported and self-hosted, add the header in your own server config (Apache `.htaccess` or Nginx server block) and ensure only one source sets it.
X frame options weakQuick win

Change the X-Frame-Options response header from its current weak or missing value to either DENY or SAMEORIGIN so your store cannot be embedded in a malicious iframe.

On Webflow

  1. Webflow hosting does not currently expose a UI to set custom HTTP response headers for page responses.
  2. Route your Webflow site through Cloudflare: point your custom domain's DNS to Cloudflare (proxied), then in Cloudflare dashboard → Rules → Transform Rules → Modify Response Header → Create rule → Add header: X-Frame-Options = DENY, apply to hostname matching your domain.
  3. If exporting Webflow code and self-hosting on Nginx: add add_header X-Frame-Options "DENY" always; inside your server {} block.
  4. If self-hosting on Apache: add Header always set X-Frame-Options "DENY" to your .htaccess or VirtualHost config.
  5. Verify the header is present after applying the rule using DevTools or securityheaders.com.

Site Lifecycle · 12 fixes

Cms versionModerate effort

Identify your ecommerce platform and CMS version, then ensure it is always kept up to date to protect your store from security vulnerabilities and avoid loss of vendor support.

On Webflow

  1. Webflow is a SaaS platform — core hosting and security updates are managed by Webflow automatically.
  2. Log in to Webflow Designer → check for any designer version update prompts or changelogs in the Webflow dashboard.
  3. Go to your Webflow Dashboard → Apps & Integrations: review all connected apps for supported status.
  4. If using Webflow Commerce, check the Webflow Commerce changelog for any feature changes that require configuration updates on your part.
Domain expiryQuick win

Enable auto-renew on your domain registration and set calendar reminders well before expiry to prevent accidental loss of your store's address.

On Webflow

  1. For domains purchased through Webflow: open the Project → Publishing → Custom Domain. Click the gear icon next to the domain to view renewal details. Webflow auto-renews Webflow-purchased domains; confirm your billing card is valid under Account → Billing.
  2. For externally registered domains: log in to your registrar, enable auto-renew, and verify payment details.
  3. Check that the email address on your Webflow account is current so you receive renewal notices.
Gtm auditModerate effort

Install Google Tag Manager on your store and configure GA4 with ecommerce event tracking (view_item, add_to_cart, purchase) so you can measure what's driving revenue.

On Webflow

  1. In Webflow Designer, go to Project Settings → Integrations → Google Tag Manager, enter your GTM Container ID, and click Save. Webflow injects the GTM snippets on all pages automatically.
  2. For Webflow Ecommerce event tracking (view_item, add_to_cart, purchase), you must push custom dataLayer events using Webflow Interactions or embed custom JavaScript in page embeds on product pages, cart pages, and the order confirmation page.
  3. Use a service like 'Littledata' or custom code embedded via Webflow's Embed element to populate the ecommerce dataLayer on key pages.
  4. In GTM, create GA4 Configuration and Event tags. Test with GTM Preview and GA4 DebugView, then publish the container.
Html langQuick win

Add a correct `lang` attribute to your site's `<html>` tag so browsers, search engines, and assistive technologies know what language your store is written in.

On Webflow

  1. In the Webflow Designer, open your Project Settings (gear icon in the top-left or via the dashboard).
  2. Go to the Localization tab (if using Webflow Localization) or the General / SEO tab.
  3. For single-language sites: Webflow sets the lang attribute from your project's primary locale. Go to Project Settings › Localization and confirm or set the primary language.
  4. For multi-language sites using Webflow Localization: each locale has its own lang setting, managed in Project Settings › Localization › Locales.
  5. You can also set a custom lang attribute per page by selecting the <html> element in the Designer (click the body, then navigate up to HTML in the element panel) and adding a lang attribute in the Custom Attributes section.
  6. Publish your site and verify via View Page Source.
Lifecycle oos schema not updatedModerate effort

Update the `offers.availability` field in your Product schema to `OutOfStock` (or `PreOrder`/`Discontinued`) whenever a product sells out, so Google's data matches your real inventory.

On Webflow

  1. Webflow Commerce generates Product schema via its CMS. Open the Webflow Designer, go to your Product Collection, and locate the product template page.
  2. In the product page template, find the JSON-LD embed (usually an HTML Embed element containing a <script type='application/ld+json'> block). If availability is hard-coded as 'InStock', replace it with a dynamic CMS binding.
  3. Use a Webflow CMS field for availability: create a plain-text or option field in your Products collection called 'Schema Availability' with values like 'https://schema.org/InStock' or 'https://schema.org/OutOfStock'. Bind this field to the availability value in your JSON-LD embed using Webflow's embed + CMS variable approach.
  4. Update out-of-stock products in the CMS: go to the Webflow Editor or CMS dashboard > Products collection > open each out-of-stock product > update the 'Schema Availability' field to 'https://schema.org/OutOfStock'.
  5. For automation, use Webflow's API or a Zapier/Make integration to update the CMS field whenever inventory changes in your fulfilment system.
  6. Publish the site and validate with Google's Rich Results Test.
Lifecycle orphaned productsModerate effort

Add internal links from category pages, navigation, and related-product sections to every product page so crawlers and shoppers can find them without relying solely on your sitemap.

On Webflow

  1. In the Webflow Designer, open the CMS panel and navigate to your Products collection. Add a filter by Category (or your equivalent reference field) set to 'is empty' to find orphaned products.
  2. Edit each orphaned product's CMS item and populate the Category (or Collection) reference field to link it to a relevant category.
  3. Ensure your Category Collection pages have a Collection List bound to Products filtered by that category — this auto-generates the link from category page to product.
  4. Add the category pages to your site navigation: in the Designer, click your Navbar element and add a link or dropdown item pointing to the relevant category pages.
  5. For related products: add a Collection List element to your Product Template page in the Designer, bound to the Products collection with a filter for 'Same Category', to auto-generate related product links.
  6. For contextual links in blog/CMS posts: edit the Rich Text element in the relevant CMS item and hyperlink product mentions to the product page slug.
Lifecycle products missing from sitemapModerate effort

Add every canonical product URL to your XML sitemap so search engines can discover and index your products faster.

On Webflow

  1. Go to Webflow Designer → Project Settings (the gear icon) → SEO tab → scroll to Sitemap → ensure 'Auto-generate sitemap' is turned ON.
  2. For each CMS collection used for products, make sure items are published: in the CMS editor, confirm no product items are in Draft status.
  3. Individual collection items can be excluded from the sitemap — open the CMS item and check that 'Exclude from sitemap' (under SEO settings within the item) is NOT checked.
  4. After publishing, verify yourdomain.com/sitemap.xml lists all product pages, then submit to Google Search Console.
Lifecycle products too deepModerate effort

Reduce the number of clicks required to reach every product page to 4 or fewer from the homepage by flattening your site structure or surfacing buried products on shallower category pages.

On Webflow

  1. Webflow Designer → Pages panel: review the CMS Collection hierarchy. Avoid chaining Collection List pages more than two levels deep (e.g. a Collection List inside a Collection List page already adds clicks).
  2. In the Webflow CMS, add a new field (e.g. a 'Featured' toggle) to your Product collection. Filter a Collection List on the homepage to show featured/buried products directly, cutting their depth to 1 click.
  3. Edit the main Navigation component in the Designer: add a Dropdown menu item that links directly to the deeply nested Collection page or individual Product page slug.
  4. On top-level Category pages, add an additional Collection List bound to 'Products' and filter it by the relevant sub-category field so those products appear on the shallower page.
  5. Use Webflow's Finsweet CMS Filter or CMS Nest attributes to surface cross-category products without restructuring your URL hierarchy.
  6. Publish changes and run a crawl (Screaming Frog or similar) to verify no product sits deeper than 4 clicks from the homepage.
Mixed contentModerate effort

Audit every page, asset, and third-party embed on your store to ensure no HTTP resources are loaded on HTTPS pages, and fix any mixed-content violations before they silently break security warnings or block content in visitors' browsers.

On Webflow

  1. Webflow serves all published sites over HTTPS by default; mixed content typically comes from custom code embeds or external asset references.
  2. In the Webflow Designer, open the Pages panel and check any Embed elements (Add Elements → Components → Embed) for http:// URLs in their HTML code; update to https://.
  3. Go to Project Settings → Custom Code (Head Code / Footer Code) and review all injected scripts, stylesheets, and iframes for HTTP URLs; update to HTTPS.
  4. On individual pages, check Page Settings → Custom Code for any page-level head/footer code with HTTP references.
  5. In the Assets panel, all assets uploaded directly to Webflow are served over HTTPS. If you reference external images via URL in style or content fields, ensure they use https://.
  6. Add <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> in Project Settings → Custom Code → Head Code as a safety net.
  7. Publish your site and verify with browser DevTools (Console tab) that no mixed-content warnings appear.
Mobile viewportQuick win

Confirm your store has a correct responsive viewport meta tag so it displays properly on phones and tablets.

On Webflow

  1. Webflow automatically includes the correct responsive viewport meta tag on all published projects.
  2. To verify or customize: open your Project Settings in the Webflow Designer, go to the 'Custom Code' tab, and check the 'Head Code' section for any conflicting or duplicate viewport tags.
  3. Remove any custom viewport tags that conflict with Webflow's default (e.g., ones with 'user-scalable=no'), and leave Webflow to render the correct tag automatically.
  4. Publish the project and confirm with Google's Mobile-Friendly Test.
Server versionModerate effort

Remove or suppress the Server version header so your web server software and version number are no longer exposed in every HTTP response.

On Webflow

  1. Webflow is a fully hosted platform — you do not control the underlying server configuration.
  2. Webflow manages HTTP response headers centrally; owners cannot modify the `Server` header from the Designer or dashboard.
  3. If you are running Webflow behind a custom reverse proxy or CDN (e.g., Cloudflare), you can add a 'Transform Rule' or 'Response Header' rule in Cloudflare to remove the Server header: Cloudflare Dashboard → your domain → Rules → Transform Rules → Modify Response Header → Add rule to remove 'Server' and 'X-Powered-By'.
  4. Otherwise, contact Webflow Support to report the finding.
Ssl expiryQuick win

Monitor your SSL/TLS certificate expiry date and set up auto-renewal so your store never goes offline or shows a security warning to shoppers.

On Webflow

  1. Webflow automatically provisions a free SSL certificate via Let's Encrypt for all published sites on custom domains.
  2. To verify: Webflow Designer → Project Settings → Hosting → Custom Domains — each connected domain will show an SSL status badge.
  3. If a domain shows 'SSL error', remove and re-add the domain, then confirm the DNS records (A record and CNAME) match exactly what Webflow specifies in the Hosting tab.
  4. Webflow handles renewal automatically; no manual renewal action is required from the owner.

Generative Engine Optimization · 9 fixes

Ai crawler blockedQuick win

Your robots.txt explicitly blocks one or more AI assistants from crawling your store, so those engines can't discover, index, or cite your products when shoppers ask for recommendations.

On Webflow

  1. Open Project Settings > SEO > Indexing > robots.txt.
  2. Remove the 'Disallow: /' rule under the AI bot's user-agent, or add an explicit 'User-agent: <bot>' then 'Allow: /'.
  3. Publish the site and verify at https://yourdomain.com/robots.txt.
Ai crawler not specifiedQuick win

Your robots.txt doesn't explicitly allow several AI crawlers. They aren't blocked, but a number of AI engines act on explicit permission, so naming them removes any ambiguity.

On Webflow

  1. Open Project Settings > SEO > Indexing > robots.txt.
  2. Remove the 'Disallow: /' rule under the AI bot's user-agent, or add an explicit 'User-agent: <bot>' then 'Allow: /'.
  3. Publish the site and verify at https://yourdomain.com/robots.txt.
Geo brand name inconsistentModerate effort

Your brand name appears in multiple different formats across your site (schema, og:site_name, footer, logo). AI engines may treat the variants as separate entities.

On Webflow

  1. Add or extend JSON-LD via an Embed element on the Collection (product) template, binding CMS fields for name/price/image/sku.
  2. Add a global Organization JSON-LD with sameAs in Project Settings > Custom Code (head).
  3. Publish and validate with Google's Rich Results Test.
Geo eeat trust signals weakModerate effort

Your store is missing trust signals (E-E-A-T) that AI engines and shoppers look for before recommending a store: clear policies, real contact details, and a credible business identity.

On Webflow

  1. Add or extend JSON-LD via an Embed element on the Collection (product) template, binding CMS fields for name/price/image/sku.
  2. Add a global Organization JSON-LD with sameAs in Project Settings > Custom Code (head).
  3. Publish and validate with Google's Rich Results Test.
Geo faqpage missing productsModerate effort

Your product pages don't use FAQPage schema, so AI assistants can't pull direct answers to common buyer questions (sizing, materials, shipping) about your products.

On Webflow

  1. Add or extend JSON-LD via an Embed element on the Collection (product) template, binding CMS fields for name/price/image/sku.
  2. Add a global Organization JSON-LD with sameAs in Project Settings > Custom Code (head).
  3. Publish and validate with Google's Rich Results Test.
Geo price not crawlableModerate effort

Your product prices appear to be rendered by JavaScript and may not be present in the static HTML, so AI crawlers (which often don't run JS) can't read or cite them.

On Webflow

  1. Add or extend JSON-LD via an Embed element on the Collection (product) template, binding CMS fields for name/price/image/sku.
  2. Add a global Organization JSON-LD with sameAs in Project Settings > Custom Code (head).
  3. Publish and validate with Google's Rich Results Test.
Geo schema org missing sameasModerate effort

Your Organization schema has no sameAs links to your social profiles, Wikipedia, or other authoritative sources - so AI engines can't confidently connect the dots about your brand.

On Webflow

  1. Add or extend JSON-LD via an Embed element on the Collection (product) template, binding CMS fields for name/price/image/sku.
  2. Add a global Organization JSON-LD with sameAs in Project Settings > Custom Code (head).
  3. Publish and validate with Google's Rich Results Test.
Geo schema product incompleteModerate effort

Your Product structured data is missing fields AI engines rely on to cite your products accurately (price, availability, currency, brand, ratings).

On Webflow

  1. Add or extend JSON-LD via an Embed element on the Collection (product) template, binding CMS fields for name/price/image/sku.
  2. Add a global Organization JSON-LD with sameAs in Project Settings > Custom Code (head).
  3. Publish and validate with Google's Rich Results Test.
Llms txt missingQuick win

Your store has no llms.txt - the emerging standard (like robots.txt, but for AI) that tells language models which content to read and cite. SEOLZ has generated a ready-to-upload file from your own pages.

On Webflow

  1. Webflow can't serve an arbitrary root .txt directly; host llms.txt on your CDN or use a reverse proxy / Cloudflare Worker mapping /llms.txt to the generated content.
  2. Verify at https://yourdomain.com/llms.txt.