Build a theme section
Write a section in the theme code editor, give it settings, inline editing and style controls, place it in the Customizer and publish it. About fifteen minutes.
On this page
You add a USP strip to a theme: one line of reassurance such as "Free delivery over 50", with an alignment choice, text merchants edit in place, and the Customizer's spacing, background, typography and visibility controls. Then you place it on the home page and publish it.
Follow https://developers.poltura.com/themes/build-a-section.md and keep to the theme rules in https://developers.poltura.com/ai/rules/AGENTS.md. Write a Poltura theme section in src/sections/usp-strip.tsx with defineSection from @poltura/theme-sdk/elements. It has a text setting with a default, an alignment select (left, center), EditableText for the text, and the style list spacing, background, typography and visibility. Spread attrs onto the one root element and merge classes with cn from @poltura/theme-sdk/ui. Import only from @poltura/theme-sdk modules, react and the theme's own files. Do not use em dashes in default copy.
Before you start
- A Poltura store where you can edit the online store's theme.
- Nothing to install. Theme code is written in the theme code editor, which runs in the browser and checks your code on every save.
Open the theme code editor
In the admin, open Online store → Themes and choose Edit in code editor on the theme you want to change. The Customizer's top bar links to the editor too.
The editor works on the theme's draft. Saving never changes the live storefront. Publishing is a separate step at the end.
Create the section file
Open the command palette (Cmd+Shift+P on a Mac, Ctrl+Shift+P elsewhere)
and run Theme: New Section…. Name it usp-strip. The editor writes src/sections/usp-strip.tsx with a
working starter: a heading, a text, a slot for child blocks and the standard style list.
There is no registry to update. The theme compiler finds every defineSection in src/sections/ on save.
Write the section
Replace the file's content with this:
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',
description: 'One short line of reassurance',
icon: 'section',
category: 'marketing',
settings: {
text: field.text({ label: 'Text', default: 'Free delivery over 50' }),
alignment: field.select({
label: 'Alignment',
options: [
{ value: 'left', label: 'Left' },
{ value: 'center', label: 'Center' },
],
default: 'center',
}),
},
style: ['spacing', 'background', 'typography', 'visibility'],
component: ({ settings, attrs }) => (
<section {...attrs} className={cn(attrs.className, 'py-6')}>
<div className='theme-container'>
<EditableText
setting='text'
as='p'
className={cn('text-foreground', settings.alignment === 'center' && 'text-center')}
/>
</div>
</section>
),
});What each part does:
typeis the section's permanent key in the theme's page files. Keep it once merchants use the section. To rename it later, list the old key inrenamedFrom.label,description,iconandcategoryare what merchants see in the Customizer's section picker.marketinglists it under Marketing.settingsbecome the fields of the section's inspector. Eachfield.*builder has a label and a default, and the component receives the values already typed assettings.stylelists the style controls merchants get. The platform turns their choices into classes and attributes onattrs.attrsmust be spread onto exactly one root element, withcn(attrs.className, ...)to merge your own classes. Without it, the style controls do nothing.EditableTextrenders thetextsetting and lets merchants edit it in place on the canvas.
Every field and style control is listed in Sections, blocks and element styles.
Save and read the check
Save the file. The editor runs the theme check on every save and lists anything wrong in the Problems panel, with the line and column. The section above passes. These are the mistakes it catches most often, with the message you get (the last one is shortened):
src/sections/usp-strip.tsx(26,19): [usage] reads setting "txt" no element definition declares for usp-strip (declared: text, alignment)
src/sections/usp-strip.tsx(18,7): [types] Type '"middle"' is not assignable to type '"center" | "left" | undefined'.
src/sections/usp-strip.tsx(5,3): [elements] type "UspStrip" must be kebab-case starting with a letter (bad-definition)
src/sections/usp-strip.tsx(2,21): [import] Theme file src/sections/usp-strip.tsx imports "lodash", which is outside the theme surface.The full import message lists what a theme may import: @poltura/theme-sdk/*, the theme's own files, React,
and a fixed set of libraries such as @radix-ui/*, lucide-react, motion and clsx.
Fix them until the panel is empty.
Place it in the Customizer
In the admin, choose Customize on the theme. On the home page choose Add section, find USP strip under Marketing and add it. You see:
- "Free delivery over 50" on the canvas. Click it and type to change it.
- Alignment with Left and Center in the section's settings.
- Spacing, Background, Typography and Visibility in its style controls.
The Customizer writes the placement into the draft's pages/home.json. Your section's code stays in
src/sections/usp-strip.tsx.
Publish
Choose Publish in the Customizer (or Publish in the code editor's status bar). The draft's code and layout go live together. Until then, shoppers see the previous version.
Go further
- Child blocks: let merchants add blocks inside the section with
blocks: { accepts: [...] }and render them with<Slot />. The starter file the editor wrote shows the pattern. - Limit where it appears:
templates: ['home', 'page']keeps it off product and cart pages. - Translate the picker:
i18n: { hu: { label: '...' } }on the section and on each field. - Draw store data: read products with the hooks of
@poltura/theme-sdk/dataand draw prices with the parts of@poltura/theme-sdk/price.
The USP strip example is this section with the first three steps done: usp-item child
blocks, a starting preset, three templates and Hungarian labels.