---
name: build-components
description: Builds Seamble components, the JS and CSS behind a snippet a Squarespace owner pastes once into a Code Block. Covers the mount contract, the rules that keep a component from breaking the site, and the build, preview and ship loop. Use before writing or changing a component's code.
---

# Build Seamble components

A component is one JS file and one CSS file behind a **snippet** the owner pastes once into a
Squarespace Code Block (`get_code` returns it). Every later change ships behind the snippet:

```html
<div data-seamble-name="sale-countdown" data-seamble-id="k7mq"></div>
<link rel="stylesheet" href="https://cdn.seamble.com/c/k7mq.css">
<script defer src="https://cdn.seamble.com/c/k7mq.js"></script>
```

The `div` is the **mount**. Write `__ID__` wherever the component id goes; saving fills it in.
Start the JS from this **starter**:

```js
(() => {
  "use strict";
  const ID = "__ID__";
  const init = (el) => { el.innerHTML = `<div class="sb-box">…</div>`; };
  const run = () => document.querySelectorAll(`[data-seamble-id="${ID}"]:not([data-sb-state])`).forEach((el) => {
    el.dataset.sbState = "loading";
    try { init(el); el.dataset.sbState = "loaded"; }
    catch (err) { el.dataset.sbState = "error"; console.error(`[seamble ${ID}]`, err); }
  });
  if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", run, { once: true });
  else run();
})();
```

## Rules

1. One classic script in the starter's shape: no `import`/`export`, TypeScript or JSX.
2. Find mounts only by `data-seamble-id`. A page may have zero, one or many; init each once.
3. Render into the mount. Put text you didn't write in with `textContent`.
4. Start every CSS selector with `[data-seamble-id="__ID__"]`; prefix your classes `sb-`.
5. Colors, fonts and spacing come from the site's variables, each ending in a hard default:
   `var(--sb-accent, var(--primaryButtonBackgroundColor, #111))`. Reserve the mount's height.
6. Values the owner may change (dates, labels, items) are JS constants: no re-pasting.
7. Anything you change outside the mount, undo in Squarespace's edit mode.

## Build, preview, ship

1. New: `create_component` with your JS and CSS. Change: `get_source`, then edit that code; a
   **preset** (ready-made component) comes back minified, so rewrite it in the starter's shape.
2. `update_component` with the full JS and CSS (`page` picks the preview page). Fix every
   warning and save again.
3. Open `preview_url`: your draft on the real page, in that browser only (`preview` makes a new
   link). Done when every mount has `data-sb-state="loaded"`, the console has no `[seamble …]`
   errors, and it works on a light and a dark section, at 375px, with two mounts, by keyboard.
4. `publish` when the owner says to ship. Before the snippet is on any page, you may publish
   the first build.

## References

Read only those whose condition matches the task.

- [Squarespace](references/squarespace.md): reads or changes the page around the mount (sections, popups, list sections, a blog), or must undo itself in edit mode.
- [Styling](references/styling.md): theme colors, heading and font variables, Squarespace buttons, spacing, responsive layout.
- [Runtime](references/runtime.md): per-mount settings (`data-*`), a library, or code that differs between preview and live.
- [Quality](references/quality.md): controls, images, timers, popups, fetched data or changing content.
- [Examples](references/examples.md): countdowns and timers, FAQs and accordions.
- [Example: tabs](references/examples-tabs.md): tabs over sections, or hiding and restoring sections.
- [Troubleshooting](references/troubleshooting.md): it doesn't show, doesn't change, or differs between preview and live.
