> ## Documentation Index
> Fetch the complete documentation index at: https://docs.exclusivo.one/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom code

> Add your own CSS and JavaScript — analytics tags, chat widgets, and tweaks the theme can't reach.

Paste in your own CSS and JavaScript to do the things the theme settings don't
cover — an analytics tag, a chat widget, a layout tweak.

## You'll need your own domain first

Custom code only runs on your own domain. On a `stashed.one` address, it won't
run at all.

The short version: on our domain, every shop shares one origin with every other
shop and with the dashboard, so a script there could read other merchants'
sessions. On your own domain, your script only ever touches your own site and
your own shoppers — which is the deal you're signing up for anyway.

→ [Set up a custom domain](/stashed/storefront/domains)

## Your code runs exactly as you wrote it

We don't sanitise it. There's no sensible way to sanitise a script you're
explicitly asking us to run, so what you save is what executes.

Three things follow from that:

<AccordionGroup>
  <Accordion title="A third-party snippet can see everything on the page">
    A chat widget or analytics tag can read what your shoppers are looking at and
    send it wherever it likes. Only paste snippets from people you'd trust with
    that.
  </Accordion>

  <Accordion title="A typo can take the page down">
    Nothing checks your syntax before it ships. Save, then open your shop with
    the browser console up.
  </Accordion>

  <Accordion title="Anything you put here is public">
    Every visitor can read it. API keys, tokens and private URLs don't belong in
    custom code.
  </Accordion>
</AccordionGroup>

## Two that catch people out

<Warning>
  Don't put `overflow-x: hidden` on `body` or `main`. It silently kills every
  sticky element on your site — sticky header, sticky filters, sticky add-to-cart.
  On `<html>` it's fine.
</Warning>

If you're adding your own structured data, escape it properly. `JSON.stringify`
won't escape a `</script>` inside a string, so a product description containing
one can break out of the block.

## Check the settings first

Quite a lot of what people reach for custom code to do is already a setting:

<CardGroup cols={2}>
  <Card title="Appearance" icon="wand-magic-sparkles" href="/stashed/storefront/appearance">
    Colours, logo, theme, policy pages.
  </Card>

  <Card title="Page builder" icon="table-cells" href="/stashed/storefront/page-builder">
    Sections, layouts, product grids.
  </Card>

  <Card title="SEO & social" icon="magnifying-glass" href="/stashed/storefront/seo">
    Titles, descriptions, link previews.
  </Card>

  <Card title="Apps" icon="plug" href="/stashed/growth/apps">
    Integrations that don't need a script at all.
  </Card>
</CardGroup>
