Structured data mastery

Product schema for Squarespace

What Squarespace's commerce templates ship by default, what they leave out, and the code injection patterns that close the gap on a closed platform.

7 min read Updated May 1, 2026

Squarespace gives you the least flexibility of any major commerce platform. The template engine is closed; theme files aren’t user- editable; there’s no equivalent of Shopify Liquid or BigCommerce Stencil. The schema layer either works for the catalog or it doesn’t, and the workarounds run through Code Injection — a feature Squarespace deliberately limits.

This guide is short because the platform forces it to be. What Squarespace ships, where it falls short, and the realistic extension options.

What Squarespace ships

The current Squarespace 7.1 commerce templates generate Schema.org Product markup automatically on product detail pages with these properties:

That’s the minimum-viable bar. Squarespace does not output:

Most other platforms produce at least brand and aggregateRating in their default templates. Squarespace doesn’t.

Squarespace
commerce template

Default JSON-LD

name + description

image + sku

offers

What's missing

brand

gtin13

category

aggregateRating

All custom attributes

What Squarespace ships by default

Squarespace auto-generates baseline structured data for product pages out of the box, including Product schema with the core fields (name, image, description, price range, availability, URL). For most catalogs, that baseline is real but minimal — it covers the basics Google needs for rich image results, but lacks the attribute density and identifier rigor an AI agent uses to reason about whether a product matches a shopper query.

This guide is about extending or overriding that baseline. To go beyond the defaults — adding aggregateRating, structured brand with an IRI, custom additionalProperty attributes, complete Offer blocks — you need Code Injection.

The Code Injection workaround

Squarespace’s Settings → Advanced → Code Injection lets you inject arbitrary HTML into the <head> of every page. This is the non-paid mechanism for adding custom schema on top of the baseline.

The constraint: the injection runs on every page (header injection) or every product page (per-collection footer injection). It can’t read product-specific data from Squarespace’s catalog. Custom schema beyond the baseline has to either be:

  1. Static — add organization-level schema once, applied to every page (logo, social profiles, organization name)
  2. JavaScript-driven — read product data from the rendered DOM at runtime and emit per-product schema dynamically

Option 1 is easy and ships organization schema, which Squarespace doesn’t generate by default. Option 2 is more involved and has a serious caveat: AI agents that don’t execute JavaScript see only the default Squarespace schema, not the JS-injected version.

Static organization injection

In Code Injection → Header:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Acme Outfitters",
  "url": "https://acmeoutfitters.com",
  "logo": "https://acmeoutfitters.com/logo.png",
  "sameAs": [
    "https://instagram.com/acmeoutfitters",
    "https://twitter.com/acmeoutfitters"
  ]
}
</script>

This propagates organization identity to every AI agent that crawls the site. Cheap to add; immediate value.

JavaScript-driven product extension

In Code Injection → Footer on product pages:

<script>
(function() {
  if (!document.querySelector('.product-detail, .ProductItem')) return;

  // Read existing values from the DOM. Selectors here are 7.1-specific
  // and may need adjustment for older templates.
  const name = document.querySelector('h1.ProductItem-details-title')?.textContent?.trim();
  const price = document.querySelector('.product-price .product-price-original')?.textContent?.replace(/[^\d.]/g, '');
  const desc = document.querySelector('.ProductItem-details-excerpt')?.textContent?.trim();

  // Brand, GTIN, category aren't exposed in the rendered DOM by default.
  // The pattern below assumes you've stored them in a custom block on
  // each product page or in a global lookup table maintained outside
  // Squarespace. There's no clean way to source them otherwise.
  const productId = document.querySelector('[data-product-id]')?.dataset?.productId;
  const productMeta = window.__customProductMeta?.[productId] || {};

  const schema = {
    '@context': 'https://schema.org',
    '@type': 'Product',
    name,
    description: desc,
    offers: {
      '@type': 'Offer',
      price,
      priceCurrency: 'USD',
      availability: 'https://schema.org/InStock'
    },
    ...(productMeta.brand && { brand: { '@type': 'Brand', name: productMeta.brand } }),
    ...(productMeta.gtin13 && { gtin13: productMeta.gtin13 }),
    ...(productMeta.category && { category: productMeta.category })
  };

  const script = document.createElement('script');
  script.type = 'application/ld+json';
  script.textContent = JSON.stringify(schema);
  document.head.appendChild(script);
})();
</script>

This pattern works for Google’s crawler (which renders JavaScript) but is missed by ChatGPT and Perplexity’s text-based crawlers. Useful for paid Google Shopping but doesn’t move the AI surfacing needle.

Q&A pairs as a sibling FAQPage block

If the product page uses Squarespace’s “Accordion” block for Q&A content, you can pipe that content into FAQPage schema with a JS injection. FAQPage is its own Schema.org type — it lives in a separate <script type="application/ld+json"> block alongside any Product schema, not nested inside it.

In Code Injection → Footer on product pages:

<script>
(function() {
  const accordions = document.querySelectorAll('.accordion-item');
  if (!accordions.length) return;

  const entries = Array.from(accordions).map(item => {
    const q = item.querySelector('.accordion-item__title')?.textContent?.trim();
    const a = item.querySelector('.accordion-item__description')?.textContent?.trim();
    if (!q || !a) return null;
    return {
      '@type': 'Question',
      name: q,
      acceptedAnswer: { '@type': 'Answer', text: a }
    };
  }).filter(Boolean);

  if (!entries.length) return;

  const schema = {
    '@context': 'https://schema.org',
    '@type': 'FAQPage',
    mainEntity: entries
  };

  const script = document.createElement('script');
  script.type = 'application/ld+json';
  script.textContent = JSON.stringify(schema);
  document.head.appendChild(script);
})();
</script>

The script reads the rendered Accordion at runtime and emits the FAQPage block. Same SSR caveat as the rest of the Squarespace patterns — JS-injected schema is missed by crawlers that don’t execute JavaScript.

This is the rendering pattern. Note that testing in late 2025 suggests that AI agents may not consistently extract JSON-LD on direct page fetch; the value of structured Q&A markup appears to come through index and feed paths rather than agents reading the page directly.

The realistic options for Squarespace catalogs

Three honest paths:

  1. Stay on Squarespace, accept the schema limitations. AI surfacing will be weaker than the same catalog on Shopify or WooCommerce. Compensate by pouring effort into product titles, descriptions, and Google Merchant Center feeds (where the gap is smaller).
  2. Squarespace + Schema App / similar. Schema App has a Squarespace integration that injects per-product schema via their own JavaScript. Same SSR caveat applies — useful for Google, limited for ChatGPT/Perplexity.
  3. Migrate. For catalogs above ~500 SKUs where AI surfacing matters, the Squarespace constraints become harder to work around. Shopify and BigCommerce both have richer schema layers and proper template editing.

Where it breaks

The contrarian take

Most Squarespace SEO content recommends Schema App or similar third- party services for schema. They do help. But because custom schema beyond the baseline rides on Code Injection (often JavaScript-driven for per-product attributes), AI agents that don’t execute JavaScript will see only the default Squarespace schema — a meaningful gap on the more aggressive AI surfaces.

The honest take: if AI surfacing across multiple agents is a primary goal and the catalog is more than ~500 products, Squarespace is the wrong platform for the job. The platform’s strengths (visual templates, ease of use) come at the cost of the data layer that AI agents read. For catalogs that pick Squarespace anyway, the static organization injection is worth doing immediately; the JS product extension is a partial fix that works for some agents and not others.

What to ship this week

  1. Add the static Organization schema injection to header code. Five-minute change; immediate identity-layer benefit.
  2. Decide whether to ship the JS-driven product extension. If yes, add the per-product custom blocks to populate the brand/GTIN/ category metadata.
  3. Validate the rendered output through the Rich Results Test (which does execute JavaScript) AND the Schema.org Validator with “Disable JavaScript” set in browser DevTools (which approximates what text-only AI crawlers see).
  4. If the catalog is above 500 SKUs and AI surfacing is strategic, start the migration conversation.