Skip to content

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.

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.

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.

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: call app.ready() and paint something immediately (a skeleton or spinner), before any API call resolves. The host gives you 15 seconds to call ready before 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.

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.

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.

Listing & review guidelines — the checklist that includes these expectations alongside functional and privacy requirements.