# How themes work (/themes)

A theme is a tree of TSX components and JSON files. Sections and blocks are React components declared with `defineSection` and `defineBlock`. Page layouts, setting values and texts are JSON files beside them. Merchants arrange sections in the Customizer; you write what the Customizer cannot do.

- [Build a theme section](/themes/build-a-section): Write, check, place and publish a section, in about fifteen minutes.
- [Theme SDK reference](/themes/sdk): 25 typed modules, from cart to ui.


## Open the code editor [#open-the-code-editor]

Every store can run its own theme code. In the admin, open **Online store → Themes** and choose **Edit in code editor** on a theme. The Customizer's top bar links to the editor too.

It is a code editor in the browser, with TypeScript completions from the theme SDK, Tailwind hints, format on save, the **Theme: New Section…** command, a Changes panel and a timeline of earlier saves. Saves go to the theme's draft. Publishing is a separate step, so the live storefront does not change while you work.

A theme imports Poltura APIs from `@poltura/theme-sdk/<module>`. It may also import its own files, React and a fixed set of libraries (for example `@radix-ui/*`, `lucide-react`, `motion`, `clsx` and `zod`). When the check refuses an import, its message lists every allowed package.

## The theme tree [#the-theme-tree]

```text
theme.json                          name, schema_version, engine
settings/schema.json                generated from src/settings.ts on every save
settings/values.json                setting values
settings/presets.json               style presets the merchant switches between
pages/<template>.json               section layout per template (home, product, ...)
pages/custom/<name>.json            layouts of the merchant's custom pages
layout/header.json, footer.json     header and footer section groups
emails/<slug>.json                  email content
texts/<language>.json               the theme's own UI texts, one file per language
assets/                             images, fonts and icons the theme ships
og/<kind>.tsx                       share image templates (optional)
src/settings.ts                     the theme settings panel, written with field.*
src/sections/, src/blocks/          section and block types, one per file
src/layout/                         optional chrome in code, such as chat.tsx
src/templates/                      optional templates in code, such as pages/landing.tsx
src/components/, src/styles/        shared components and CSS
src/preview-scenarios.ts            sample data states for the Customizer
```

## Write a section [#write-a-section]

Each file under `src/sections/` or `src/blocks/` declares its type once. The compiler reads the declarations without running them and builds the Customizer's picker, the editor's layout schema and the publish checks from them. There is no registry file.

```tsx title="src/sections/usp-strip.tsx"
import { EditableText, defineSection, field } from '@poltura/theme-sdk/elements';
import { cn } from '@poltura/theme-sdk/ui';

export const uspStrip = defineSection({
  type: 'usp-strip',
  label: 'USP strip',
  icon: 'section',
  category: 'marketing',
  settings: { text: field.text({ label: 'Text', default: 'Free delivery over 50' }) },
  style: ['spacing', 'background', 'typography'],
  component: ({ attrs }) => (
    <section {...attrs} className={cn(attrs.className, 'py-6')}>
      <EditableText setting='text' as='p' className='theme-container text-center' />
    </section>
  ),
});
```

The component spreads `attrs` onto its one root element. That is how the merchant's style choices reach it. The [Build a theme section](/themes/build-a-section) tutorial walks through the whole flow, from the editor to publishing. [Sections, blocks and element styles](/themes/elements) covers settings, blocks and style capabilities.

## Style presets [#style-presets]

`settings/presets.json` lists up to eight named looks of the theme. Each preset has an id, a label, one to five `#rgb` or `#rrggbb` swatches for the picker, and a partial set of `settings/values.json` values:

```json title="settings/presets.json"
{
  "$schema": "../.schemas/presets.schema.json",
  "presets": [
    {
      "id": "bright",
      "label": "Bright",
      "label_i18n": { "hu": "Élénk" },
      "swatches": ["#ff3d7f", "#111111", "#fafafa"],
      "values": { "colors.primary": "#ff3d7f", "colors_dark.primary": "#ff8fb1", "radius": "0" }
    }
  ]
}
```

Switching to a preset changes the draft's settings only. Every look setting takes the preset's value, or else its `default` (`dark_default` for a dark twin) from `settings/schema.json`, so nothing of the previous preset survives. Content settings and every page, layout, text and email stay as they are. Ids use `a-z`, `0-9` and `-`, and `default` is reserved for the shipped look.

A setting's type decides whether it is look or content. Colours, gradients, fonts, selects, radios, numbers, ranges and checkboxes are look. Text, images, links and the rest are content. A setting overrides this with `"content": true` (a "Show the cookie bar" checkbox is the merchant's decision, not the theme's look) or `"content": false` (a text field holding a CSS length).

A preset value must name a look setting of `settings/schema.json` and fit its type. Once a theme ships presets, every look setting needs a `default`. Saving, installing, publishing and building the theme all refuse a presets file that breaks these rules.

## Check before you publish [#check-before-you-publish]

The code editor runs the theme check on every save and lists its findings in the Problems panel, each with a line and column. It checks layout files, sections, settings, imports and types.

The same check runs as `poltura theme check <dir>` on a theme directory. `--types <pack>` points it at the theme SDK's type pack, and `--json` prints one machine-readable line. The same command line can also pull a theme into a folder, push your edits to a draft, preview, publish and roll back: see [Theme commands](/themes/cli). (Not published to npm yet.)

## Next [#next]

- [Build a theme section](/themes/build-a-section): The tutorial: write, check, place and publish a section.
- [Sections, blocks and element styles](/themes/elements): defineSection, defineBlock, fields and styles.
- [Server rendering](/themes/server-rendering): Rules for code that renders on the server.
- [Theme SDK reference](/themes/sdk): 25 typed modules, from cart to ui.
