Design guidelines
Your app runs in a cross-origin iframe with its own styling — OneBooks can’t enforce how it looks. These guidelines are what makes the difference between an app that feels bolted-on and one that feels native.
Respect the host’s chrome
Section titled “Respect the host’s chrome”On your home page and in action dialogs, the host already wraps your app in a
chrome bar naming your app and developer, with its own close button in a
dialog — deliberate anti-phishing UI; see
Embedded apps. Don’t duplicate it:
skip a redundant app-name header or close button inside your own page unless
your layout genuinely needs one. A block card is headed by your extension’s
label and a Provided by … line, so don’t repeat those either. To show where
the merchant is inside your app, use
app.setTitle() — it adds a secondary heading beside
your app’s name — and app.loading() for a host-drawn progress bar while you
work.
Spacing and typography
Section titled “Spacing and typography”Use generous, consistent spacing and a clean system font stack
(system-ui, or your own web font if it’s central to your brand) rather than
a dense, cramped layout — OneBooks’ own UI is spacious and card-based, and an
app that crams a data table into a 200px-tall block reads as an afterthought.
For a block extension, keep the card compact: it starts at the height you
registered (120–800 px), and if your content needs a different height, call
app.autoResize() so the card fits it rather than scrolling inside itself.
It measures your <body> content, so the card follows your content both ways
— as long as you leave <body> at its natural height, never a fixed or
100% one. Design for a card on a busy record page, not a full screen.
Theming
Section titled “Theming”Call app.context() on load to read theme ('light' | 'dark'), and
listen for the theme.changed App Bridge event
— OneBooks doesn’t reload your frame when the merchant switches, so your page
has to update itself. A block that stays white-on-white inside an otherwise
dark OneBooks session is one of the more jarring “not native” signals. The
same goes for language: handle locale.changed in place.
Read dir from context.get() ('ltr' | 'rtl') and mirror your layout for
Arabic — flip alignment, icon direction, and reading order using logical CSS
properties (margin-inline-start, text-align: start, etc.) rather than
hardcoded left/right. If you claim Arabic in your listing’s languages[],
this isn’t optional — reviewers check it.
Loading, empty and error states
Section titled “Loading, empty and error states”- Loading: call
app.ready()and paint something immediately (a skeleton or spinner), before any API call resolves. The host gives you 15 seconds to callreadybefore showing its own error state — don’t spend it on a blank white frame. - Empty: if there’s nothing to show yet (no data synced, nothing configured), say so with a clear next step — not a bare blank card.
- Error: if a call fails, show a real message and (where it makes sense) a retry action, not a silently broken page.
Accessibility
Section titled “Accessibility”Meet ordinary web accessibility basics: sufficient color contrast, visible focus states, keyboard-operable controls, and meaningful alt text/labels. Nothing here is OneBooks-specific — treat your embedded page like any other production web page, because merchants will.
Never ask for OneBooks credentials
Section titled “Never ask for OneBooks credentials”Worth repeating from Security: don’t render a login form asking for a merchant’s OneBooks email or password inside your app. Session tokens exist so you never need to.
Where next
Section titled “Where next”Listing & review guidelines — the checklist that includes these expectations alongside functional and privacy requirements.