Skip to content
50% OFF $299 $599
Lock in
§ 2.10.2 ARTICLE
Published VerifiedEvery 6 weeks Sources4 named Authored bySquareRank Team

Code Injection · § 2.10.2 · How-to

The Squarespace H1 fix — patch the multi-H1 default with Code Injection

Squarespace 7.1 tags every blog post title as H1 on the blog index page. A default index listing twelve posts ships twelve H1 elements1. Portfolio and event index pages do the same. Squarespace's framing is that Google does not penalise multiple H1s, which is correct for classical Search and incomplete for AI Overviews passage extraction. The fix is a short JavaScript Code Injection patch that re-tags collection-block H1 elements as H2 after the DOM loads, leaving the page's primary H1 untouched.

This leaf ships the audit, the editor pass for regular pages, and the production-ready Code Injection patch for collection pages. The patch is the same one referenced in the Pillar 1 AI Overviews heading hierarchy leaf; this article focuses on the Code Injection mechanics and validation rather than the AIO context.

The multi-H1 problem on Squarespace

Two default behaviours produce multi-H1 pages on a fresh Squarespace 7.1 site. On collection index pages — blog, portfolio, events — the platform tags each item title with H1, so a page listing twelve posts renders twelve H1 elements. On regular section-based pages, the editor's tag dropdown allows any text block to be set to H1, and section-based design encourages designers to set hero-section text as H1 because the visual style looks right. The combination produces pages with H1 elements scattered through the body and a default editorial workflow that no in-editor warning catches.

Squarespace's own help article1 confirms the collection-page behaviour: "On collection pages (blogs, events, portfolios), Squarespace automatically applies H1 tags to item titles. For instance, blog post titles receive H1 tags both on blog index pages and individual post pages in Version 7.1." The article frames this as accessibility-positive and SEO-neutral, citing Google's relaxed multi-H1 stance.

The framing is honest as far as classical Search goes. Google has stated for years that multiple H1 elements are not a ranking factor2. What changed between 2024 and 2026 is the rise of passage-based extraction layers that read sub-sections of pages and cite them as standalone snippets. Search Engine Land's 2026 GEO guide3 describes the change: AI engines "break pages into individual passages" and choose between them based on the heading hierarchy. A page with twelve H1 elements does not break into clean passages because the heading hierarchy provides no segmentation signal.

The numbers behind the patch

12+

H1 elements a default 7.1 blog index emits — one per visible post title.

Squarespace Help · 2026
1

primary H1 per page — the discipline AIO passage extraction reads cleanly.

Search Engine Land · 2026-02-23
~5min

to audit a Squarespace site, run the editor pass, and ship the Code Injection patch.

Squarespace Help · 2026

Audit the live HTML in 60 seconds

Open the page in a private browser window. View source. Use the browser's find-on-page for the string '<h1' and count the results. Anything more than one is a candidate for review. Run the audit on your homepage, your top three blog posts, your blog index, your service page, and your about page. Most Squarespace 7.1 sites surface three to eight pages with multiple H1 elements on the first pass; collection index pages are guaranteed to fail until they are patched.

View-source is more reliable than the editor's audit because the editor only shows what you authored, not what the platform emits at render time. Collection item titles are tagged H1 by the platform; the editor will not surface them as H1 in its UI because they live inside the collection block. View-source is the authoritative read.

bash Optional: run the audit from the command line if you prefer scripting it
 # Counts H1 elements on a live page
curl -s https://yoursite.com/blog/ | grep -oE "<h1[^>]*>" | wc -l # Expected on a clean detail page: 1 # Typical on a default 7.1 blog index: 12+ (one per visible post) 

Editor-only fix for normal pages

On any page that is not a collection index, the fix is editor-only. Open the page in the Squarespace editor. Click each text block that the audit flagged as H1. Use the tag dropdown to change it to H2 if it is a major section heading, or H3 if it is a nested sub-point. Leave only the page's primary headline as H1. Save. Re-run the view-source audit and confirm a single H1 remains.

Two editor-side gotchas. First, the visual style of H2 in some 7.1 templates is much smaller than the H1 style designers were aiming for. The fix is CSS customisation in Design → Custom CSS, not reverting the tag. Second, the editor occasionally re-renders a saved page before the tag change is reflected in the live HTML; if the view-source audit still shows H1, hard-refresh and re-check before assuming the change failed.

The Code Injection patch for collection pages

Blog index pages, portfolio grids, and event lists tag their item titles with H1 at the platform level. The editor will not let you change those tags because they are emitted by the collection block, not by an author-controlled text block. The workaround is a short JavaScript snippet that runs after the page loads and re-tags the offending H1 elements as H2. The patch is intentionally conservative: it scopes the re-tag to collection-block H1 elements only, leaves the page's primary H1 untouched, and runs once at DOMContentLoaded with no observer overhead.

HTML / JS The H1 patch — paste into Page Settings > Advanced > Page Header Code Injection on the collection page
 <!-- Heading hierarchy patch: re-tag collection item H1s as H2 --> <!-- Scope: collection blocks only. Primary page H1 left untouched.  --> <!-- Tested: Squarespace 7.1 blog, portfolio, events collections.   --> <script>
document.addEventListener("DOMContentLoaded", function() { const selectors = [
".blog-item-title h1", ".blog-basic-grid h1", ".portfolio-grid h1", ".events-collection h1"
];
selectors.forEach(function(sel) {
document.querySelectorAll(sel).forEach(function(el) { const h2 = document.createElement("h2");
h2.innerHTML = el.innerHTML; for (const attr of el.attributes) {
h2.setAttribute(attr.name, attr.value); }
el.parentNode.replaceChild(h2, el); }); }); }); </script> 

The patch fires at DOMContentLoaded, scopes itself to collection block selectors only, and preserves every original attribute on the element (class, id, data-* attributes) so the styling is unchanged. The visible page looks identical to a human reader; the DOM that crawlers and AI engines read is now segmented cleanly.

Where to paste the patch

The patch belongs in Page Settings > Advanced > Page Header Code Injection on the specific collection page (blog index, portfolio index, events index). Per-page placement keeps the patch scoped to the pages that need it and avoids the overhead of running the script on every page on the site. Per-page Code Injection requires Business plan or above; on Core or Plus plans, the patch can live in the site-wide Header field but will run on every page load.

Validate after deployment

After saving the panel, reload the collection page in a private browser. View source first — the source will still show H1 because view-source returns the pre-script HTML. Then open the browser's developer tools, inspect the page, and confirm the collection item titles now render as H2 in the live DOM. Both views are accurate: the source HTML still has H1 (because that is what Squarespace emits), and the DOM has H2 (because the script re-tagged them after parse).

Googlebot reads the rendered DOM, not the source HTML, because Googlebot runs a JavaScript rendering pass before indexing4. AI Overviews citations are eligible from the rendered DOM. The patch therefore takes effect for SEO and AIO purposes immediately on deployment; the gap between source HTML and rendered DOM is invisible to the engines that matter.

One caveat: some retrieval crawlers (notably Bytespider and certain Perplexity user-agents) do not run JavaScript before reading the page. For those crawlers, the source HTML is what they read, and the patch is invisible. The cleanest path is to pair the JavaScript patch with editorial discipline: when the editor lets you set heading tags directly, set them to H2 in the first place rather than relying on the patch to retroactively fix the rendered DOM.

Edge cases and template variations

The patch covers the three most common collection types and works on every 7.1 template family at the time of writing. Three edge cases occasionally need additional selectors. First, custom code blocks that render their own H1 elements (rare, but some imported third-party widgets do this). Second, summary blocks that aggregate posts from multiple collections — these emit H1 elements outside the .blog-item-title scope and need a custom selector. Third, sites using third-party plugins that inject their own H1-tagged content.

The fix for each edge case is the same: identify the offending selector via view-source, add it to the selectors array in the patch, and re-deploy. On 7.0 sites, the selector names differ by template family (Brine, Bedford, York), and the patch needs to be customised. The 7.0 vs 7.1 AIO compatibility leaf covers the family-specific differences. For 95 percent of 7.1 sites, the patch above ships unmodified and works correctly.