Squarespace code block: add HTML, CSS and JavaScript

A Squarespace Code block is a box on a page that takes HTML. CSS goes inside style tags, scripts go inside script tags, and the Type must be set to HTML or the code shows as text.

In Squarespace, a Code block is a block you add to a page and fill with HTML. Set its Type to HTML, wrap CSS in <style> tags and JavaScript in <script> tags, and the block shows the result instead of the code.

Here, "code block" means this Squarespace block, not a styled box for showing source code.

Try the whole snippet first. It is the style, the markup and the script a block would hold, shown as a page you can click.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Code block snippet</title>
</head>
<body style="margin:0;padding:16px;font-family:system-ui,sans-serif;background:#f4f5f7">

<!-- Paste from here ... -->
<style>
  .sq-card { max-width: 340px; padding: 16px 18px; border-radius: 12px;
    background: #fff; border: 1px solid #dfe3ea; }
  .sq-card h3 { margin: 0 0 4px; font-size: 18px; }
  .sq-card p { margin: 0 0 12px; color: #475063; font-size: 15px; }
  .sq-card .sq-btn { padding: 10px 16px; border: 0; border-radius: 8px;
    background: #1d4ed8; color: #fff; font-size: 15px; cursor: pointer; }
  .sq-card .sq-more { margin: 12px 0 0; font-weight: 600; color: #0f5132; }
</style>

<div class="sq-card" id="sq-card-1">
  <h3>Open studio day</h3>
  <p>Saturday, 10:00 to 16:00. Everyone is welcome.</p>
  <button class="sq-btn" type="button">Show address</button>
  <p class="sq-more" hidden>12 Example Street, second floor (sample text)</p>
</div>

<script>
  // The wrapper function keeps the names private to this block
  (function () {
    var card = document.getElementById('sq-card-1');
    var btn = card.querySelector('.sq-btn');
    var more = card.querySelector('.sq-more');
    btn.addEventListener('click', function () {
      more.hidden = !more.hidden;
      btn.textContent = more.hidden ? 'Show address' : 'Hide address';
    });
  })();
</script>
<!-- ... to here -->

</body>
</html>
A card with a button. The three parts between the comments are what goes into the block.

The same three parts, without the page wrapper, look like this:

<style>
  .sq-card { padding: 16px; border-radius: 12px; background: #fff; }
</style>

<div class="sq-card" id="sq-card-1">
  <button class="sq-btn" type="button">Show address</button>
</div>

<script>
  (function () {
    var btn = document.querySelector('#sq-card-1 .sq-btn');
    btn.addEventListener('click', function () { /* toggle text here */ });
  })();
</script>

Squarespace's code blocks help page is the reference for the block itself. Everything below is about what to put inside it.

Three places code can go

A code block is one of three spots. Which one fits depends on whether the code belongs to one spot on a page, to the whole site, or to every page's header and footer.

The code block sits inside a page, the Custom CSS panel holds only styles, and code injection reaches the header and footer.
The code block sits inside a page, the Custom CSS panel holds only styles, and code injection reaches the header and footer.
Place What goes in Where it applies
Code block HTML, CSS in style tags, scripts The page, post or area holding the block
Custom CSS panel CSS only Styles you write once in a separate editor
Code injection HTML and scripts Header and footer of every page

Squarespace's custom code overview lists these side by side, along with the plans each one needs. It also says code-based customisation falls outside the scope of its support, so a working test copy of your snippet is worth having.

How to add it: 5 steps

  1. Test the snippet in one file. Write the style, markup and script together and check it works. A file you can open or share is easier to fix than a live page.
  2. Add a Code block. Edit the page, hover over the section, click Add block or +, then choose Code.
  3. Open the block editor. Click the pencil icon on the block and paste the snippet into the text field.
  4. Set the Type to HTML. CSS and JavaScript types show their code as text by default.
  5. Check the live page. If the code is invisible while you are logged in, use Preview in Safe Mode, then open the published page on a phone.

Paste a fragment, not a whole page

Your test file is a complete page, with a doctype, a head and a body. The code block is not a page. It is a spot inside one, and the page around it already has its own body.

Paste the style, the markup and the script. Leave the page wrapper in your test file.
Paste the style, the markup and the script. Leave the page wrapper in your test file.

MDN's body element page says there can be only one body in a document.

So copy from the first style tag to the last script tag and leave the wrapper behind. Page-level settings such as the viewport meta tag stay with Squarespace.

CSS in a code block: style tags and the Type setting

The most common surprise is code that appears on the page as text. Squarespace's help page says blocks set to CSS or JavaScript display their code as text by default.

With the type on CSS the visitor reads the code. With the type on HTML and style tags the browser applies it.
With the type on CSS the visitor reads the code. With the type on HTML and style tags the browser applies it.

The fix is the Type menu. Choose HTML, then put your rules between <style> and </style>. The same page names a Display Source switch, which is meant for showing code snippets to readers, so leave it off when you want the code to run.

If your CSS lives in a separate file rather than in the snippet, why CSS does not load covers that case.

Keep your CSS from restyling the whole page

MDN says CSS in a style element applies to the contents of the document containing it. A code block sits inside your Squarespace page, so its rules can reach the theme's own buttons and headings, not just your snippet.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>A bare selector restyles the whole page</title>
<style>
  body { margin: 0; padding: 14px; font-family: system-ui, sans-serif; background: #f4f5f7; color: #1d2330; }
  .modes { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
  button { padding: 7px 11px; border: 1px solid #c9cdd4; border-radius: 6px; background: #fff; color: #1d2330; font-size: 13px; cursor: pointer; }
  .modes button { padding: 8px 12px; border-radius: 8px; background: #fff; color: #1d2330; font-size: 14px; }
  .modes button[aria-pressed="true"] { background: #1d2330; color: #fff; border-color: #1d2330; }
  .page { background: #fff; border: 1px solid #dfe3ea; border-radius: 12px; padding: 12px; }
  .nav { display: flex; gap: 8px; align-items: center; padding-bottom: 10px; border-bottom: 1px dashed #c9cdd4; margin-bottom: 10px; }
  .nav b { flex: 1; font-size: 14px; }
  .label { font-size: 12px; color: #5b6270; margin: 0 0 6px; }
  .block { padding: 10px; border-radius: 8px; background: #f8f9fb; }
  pre { margin: 12px 0 0; padding: 10px; border-radius: 8px; background: #1d2330; color: #e6e9ef; font-size: 13px; line-height: 1.5; white-space: pre-wrap; }
</style>
<!-- The style element below is the one the buttons swap -->
<style id="swap"></style>
</head>
<body>

<div class="modes">
  <button type="button" id="m-none" aria-pressed="true">No code block CSS</button>
  <button type="button" id="m-bare" aria-pressed="false">Bare "button" rule</button>
  <button type="button" id="m-scoped" aria-pressed="false">Scoped ".sq-btn" rule</button>
</div>

<div class="page">
  <div class="nav"><b>Site header (your theme)</b><button type="button">Menu</button><button type="button">Cart</button></div>
  <p class="label">Code block</p>
  <div class="block"><button type="button" class="sq-btn">Book now</button></div>
</div>

<pre id="shown"></pre>

<script>
  const css = {
    none: '/* nothing added */',
    bare: 'button {\n  background: #c2410c;\n  color: #fff;\n  border-radius: 99px;\n}',
    scoped: '.sq-btn {\n  background: #c2410c;\n  color: #fff;\n  border-radius: 99px;\n}'
  };
  const swap = document.getElementById('swap');
  const shown = document.getElementById('shown');

  function pick(mode) {
    swap.textContent = css[mode];            // rules apply to the whole document
    shown.textContent = css[mode];
    for (const m of ['none', 'bare', 'scoped']) {
      document.getElementById('m-' + m).setAttribute('aria-pressed', String(m === mode));
    }
  }
  for (const m of ['none', 'bare', 'scoped']) {
    document.getElementById('m-' + m).addEventListener('click', () => pick(m));
  }
  pick('none');
</script>
</body>
</html>
Switch between no rule, a bare button rule and a scoped class rule. Watch which buttons change.

A bare button rule changed the site header too. A rule starting with a class you chose, such as .sq-btn, touched only your block. Put one prefix on every class in the snippet and start each rule with it.

If your rule seems ignored, the theme may have a rule with higher specificity. When two selectors tie, the last one declared wins. Lengthen your selector before reaching for !important, which MDN calls a bad practice.

Keep scripts from colliding

Two code blocks on one page share one global scope. MDN's let page says declaring a let or const name in one script and again in another script causes a redeclaration error.

Wrap each block's script in a function that runs at once. MDN describes this pattern, an IIFE, as a way to avoid polluting the global namespace. The snippet above does exactly that.

Place the script after the markup it touches. MDN says inline scripts run immediately, before the browser parses the rest of the page, so elements below the script do not exist yet.

A finished example: a price toggle

This one uses everything above: a class prefix on every rule, a wrapped script, and a layout that wraps on a narrow screen. Squarespace says it cannot guarantee how custom code works with its responsive design, so test at phone width.

Live exampletry it here, then copy the code
Share it as a link
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Monthly / yearly price toggle</title>
</head>
<body style="margin:0;padding:14px;font-family:system-ui,sans-serif;background:#f4f5f7">

<style>
  .sq-price { --sq-accent: #1d4ed8; max-width: 520px; margin: 0 auto; color: #1d2330; }
  .sq-price .sq-switch { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; font-size: 15px; }
  .sq-price .sq-toggle { position: relative; width: 48px; height: 28px; padding: 0; border: 0; border-radius: 99px; background: #c9cdd4; cursor: pointer; }
  .sq-price .sq-toggle::after { content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%; background: #fff; transition: transform .15s; }
  .sq-price .sq-toggle[aria-checked="true"] { background: var(--sq-accent); }
  .sq-price .sq-toggle[aria-checked="true"]::after { transform: translateX(20px); }
  .sq-price .sq-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; }
  .sq-price .sq-plan { padding: 16px; border-radius: 12px; background: #fff; border: 1px solid #dfe3ea; }
  .sq-price .sq-plan h3 { margin: 0 0 6px; font-size: 16px; }
  .sq-price .sq-amount { font-size: 30px; font-weight: 700; }
  .sq-price .sq-per { font-size: 14px; color: #5b6270; }
  .sq-price .sq-note { margin: 8px 0 0; min-height: 18px; font-size: 13px; color: #0f5132; }
  .sq-price .sq-small { margin: 12px 0 0; font-size: 12px; color: #5b6270; }
</style>

<div class="sq-price" id="sq-price-1">
  <div class="sq-switch">
    <span>Monthly</span>
    <button class="sq-toggle" type="button" role="switch" aria-checked="false" aria-label="Bill yearly"></button>
    <span>Yearly</span>
  </div>
  <div class="sq-grid">
    <div class="sq-plan"><h3>Starter</h3><span class="sq-amount" data-month="9" data-year="90">9</span><span class="sq-per"></span><p class="sq-note"></p></div>
    <div class="sq-plan"><h3>Studio</h3><span class="sq-amount" data-month="19" data-year="190">19</span><span class="sq-per"></span><p class="sq-note"></p></div>
  </div>
  <p class="sq-small">Sample prices for the demo.</p>
</div>

<script>
  (function () {
    var root = document.getElementById('sq-price-1');
    var toggle = root.querySelector('.sq-toggle');
    var plans = root.querySelectorAll('.sq-plan');

    function render(yearly) {
      toggle.setAttribute('aria-checked', String(yearly));
      plans.forEach(function (plan) {
        var amount = plan.querySelector('.sq-amount');
        var month = Number(amount.dataset.month);
        var year = Number(amount.dataset.year);
        amount.textContent = '$' + (yearly ? year : month);
        plan.querySelector('.sq-per').textContent = yearly ? ' / year' : ' / month';
        plan.querySelector('.sq-note').textContent = yearly ? 'Saves $' + (month * 12 - year) + ' a year' : '';
      });
    }

    toggle.addEventListener('click', function () {
      render(toggle.getAttribute('aria-checked') !== 'true');
    });
    render(false);
  })();
</script>

</body>
</html>
A monthly and yearly switch. Click it and the prices and the savings note change.
  • One root element: the script looks things up inside #sq-price-1, never on the whole document.
  • Data in attributes: each price carries its monthly and yearly value, so editing a price means editing one attribute.
  • Flexible layout: a grid with auto-fit columns puts two cards side by side, or stacks them on a phone.

When it does not work

What you see Cause Fix
The code appears as text Type is CSS or JavaScript, or Display Source is on Set Type to HTML, wrap CSS in style tags
Nothing shows while you edit Squarespace sometimes hides code for logged-in users Use Preview in Safe Mode
The button does nothing on the live site JavaScript needs a plan that allows it Check the plan list on the code blocks help page
Theme buttons or headings changed A bare selector such as button Start every rule with your own class
Your style is ignored A theme rule has higher specificity Lengthen the selector
The second block's script errors Both scripts declare the same name Wrap each script in a function
The script cannot find its element It runs before the markup is parsed Put the script after the markup
The block looks wrong on a phone Fixed widths in the snippet Use max-width and a flexible grid

Squarespace also sets a size limit of 400 KB on a code block, which its help page puts at around 300,000 characters. A snippet like the ones here is far below that. Large data belongs elsewhere.

A snippet is easier to review as a working page than as a description. A screenshot cannot be clicked, and an .html attachment may open as plain code on a phone. A self-contained file is the simplest thing to send.

To send the working version, paste the page into a NOS document and choose Create share link. HTML to link walks through it.

The page renders as written and its scripts run, so the person you send it to can click the card and flip the toggle. If you change the code, the same link shows the new version.

Your Squarespace theme has its own styles, so look at the final result on the real page too. For another tool that takes HTML, see embedding HTML in Notion.

Questions people ask

Can I put CSS in a Squarespace code block?

Yes. Squarespace's help page says every plan supports CSS in a code block, as long as the code is wrapped in style tags and the block Type is HTML. A block left on the CSS type shows the code as text.

Does a code block run JavaScript on every plan?

No. The help page lists JavaScript and iframes as available on the Core, Plus, Advanced, Business, Commerce Basic and Commerce Advanced plans. Plan names change, so check the code blocks page for your plan.

Should I use a code block or the Custom CSS panel for styles?

Use the Custom CSS editor for plain style rules and a code block when the HTML, CSS and script belong together in one spot on a page. Squarespace says CSS should only be used to change fonts, colors and backgrounds.

Why can I not see my code while I am logged in?

Squarespace says that as a security measure your code sometimes does not appear while you are logged in, even when visitors can see it. Choose Preview in Safe Mode on the page to view the embedded item.

Can I paste a full HTML file into a code block?

Paste only the style, markup and script parts. The page around the block already has its own body element, and MDN notes that a document can have only one. Keep doctype, html, head and body tags in your test file.

Can a code block run PHP or a database query?

No. Squarespace's help page says server-side code such as PHP, Ruby and SQL is not supported. A code block holds front-end code: HTML, CSS and JavaScript that runs in the visitor's browser.

Keep reading