Lesson 8 / 98 min read

Best practices and advanced configuration

The patterns that keep an app solid: mobile, state, failure tolerance and cost.

Five patterns

  1. 1
    Mobile first, desktop second

    Base the layout on a single column, keep tap targets ≥44px and put the primary action within thumb reach. Open the layout up on wide screens — never ship a phone tab bar to desktop.

  2. 2
    Wrap every call

    Network errors, quotas, disabled features are all normal. Catch them and show one sentence in the user's language; a raw error code must never reach the screen.

  3. 3
    Keep the server the source of truth

    Re-read the list after a write; if you update optimistically, roll back on failure. Two devices editing the same record is a real scenario.

  4. 4
    Never show an empty screen

    Loading, empty and error states all need a design. An empty state carries an action telling the person what to do next.

  5. 5
    Keep collections small

    A document caps at 20K characters; paginate large lists or split them by date. Images always live in file storage with only the URL in the record.

Fragile vs solid

Fragile
  • await devany.ai.ask(...) with no wrapper
  • An image base64'd into the record
  • A raw error code shown on screen
  • A layout only ever tried on desktop
Solid
  • try/catch and hide the feature when off
  • devany.files.upload → a URL in the record
  • Code → one sentence in the user's language
  • Tested on a phone first, then wide

The resilient call pattern

js
async function safe(fn, onFail) {
  try { return await fn(); }
  catch (e) {
    const m = {
      ai_disabled:     'Bu özellik şu anda kapalı.',
      mail_disabled:   'E-posta gönderimi kapalı.',
      quota_exceeded:  'Depolama alanı dolu.',
      file_too_large:  'Dosya çok büyük, daha küçük bir görsel seç.',
      not_signed_in:   'Devam etmek için giriş yap.',
      rate_limited:    'Çok hızlı gittik — bir dakika sonra dene.',
    }[e.message] || 'Bir şeyler ters gitti, tekrar dener misin?';
    onFail(m);
    return null;
  }
}

const summary = await safe(() => devany.ai.ask(prompt), toast);
if (summary) render(summary);

Advanced configuration: which switch, where

Where you turn it on
In-app AIBuilder → app settings
Transactional emailBuilder → email (from name, reply-to)
Webhook targetBuilder → automation (Catch Hook URL)
Visibility / private publishThe publish screen
Your own domainPublish → domain (DNS verification)
Spend cap (autonomous run)When you start the run
Campaign sendingManagement console → Campaigns
Try it yourself

Try it yourself: a resilience audit

Harden an existing app against three real failure scenarios.

  1. 1Turn in-app AI off and open the screen that uses it — does it crash or degrade politely?
  2. 2Go into airplane mode and try to add a record; is the message understandable?
  3. 3Try uploading a very large photo and watch the error.
  4. 4For each gap, write one sentence to the builder: "hide this section when AI is off".
  5. 5Repeat the pass on a phone — tap targets and horizontal overflow.
What you should end up with

An app that stays understandable with a feature off, the network gone and a file rejected.

Key takeaways

  • Every SDK call can fail; translate the code into a human sentence.
  • Mobile comes first — a wide screen opens the layout up, it doesn't copy the phone one.
  • Configuration switches live in the builder and publish screens, not in code.

Related topics

Still stuck? Ask the assistant in the corner, or browse the FAQ.