Backend SDK Integration note that window.appifio is auto-loaded
SDK bootstrap

Appifio Creator · Lesson AM09 · Globals & bootstrap

Auto-injected bootstrap
globals & a ready client

The platform injects config and the API library before your app HTML. You do not load the client script yourself - wait the right way, then call appifio_client.

Learning goals: Understand window.appifio.global.apps, why appifio_client always exists, and the waitForAppStorage pattern before every API call.

Previous: AM01 · AM08 · Next: AM10 (URLs & empty data)

Canonical source: Aura Storage API guide · globals & bootstrap

1. What is App Storage Bootstrap?

When a visitor opens an app page, the platform injects a small script (App Storage Bootstrap) into - it runs before the HTML in your app folder. Bootstrap:

  • Sets the config object window.appifio.global.apps
  • Creates the appifio_client getter (proxy or real instance)
  • Loads the Aura appifio_client library when backend = Advanced
  • Defines global helpers (waitForAppStorage, …)
Do not add a <script src="https://appifio.com/uploads/pages/appifio-am09-appifio-client-always-present.jpg"> tag yourself and do not create window.appifio - the system already did.

2. window.appifio.global.apps - app info

This object tells you where the app runs and which API endpoint to use. The client reads these values when sending requests - you rarely send them by hand.

FieldPlain meaning
url_nameApp slug on the URL - every API call includes this name
api_urlAura Storage endpoint address (single POST)
site_urlPlatform domain root - used to build absolute links (see AM10)
api_keyPage-session token - the client sends it with each request (encoded_key); not an admin password
backend_version'advanced' → Aura client (this AM series); 'easy' → simpler client
// Read when needed (e.g. build links, debug)
const urlName = window.appifio.global.apps.url_name
const siteUrl = window.appifio.global.apps.site_url.replace(/\/$/, '')
const apiUrl  = window.appifio.global.apps.api_url
After an admin logs in, the client keeps the session and sends the admin token with requests - you do not attach it to each call. Auth detail: AM06.

3. Aura CMS - extra inject (when enabled)

When Aura CMS is on, bootstrap also injects:

window.__AURA_CMS_DISPLAY_FORMATS__ = { date, time, datetime_display, timezone, ... }

This lets appifio_formatDateTime follow CMS settings - do not read cms-settings by hand. See AM08 (formatDateTime helper).

4. appifio_client - always present

Code editor showing window.appifio_client always available on the page
appifio_client present

Bootstrap uses Object.defineProperty - the getter returns a proxy or the real instance:

Stateappifio_client returns
Client script not finished loadingproxyClient - every appifio_*() is queued, then runs when ready
AppStorageClient initializedReal clientInstance
✅ Correct
await window.waitForAppStorage()
const result = await appifio_client.appifio_readList('blog.json', ['id','title'])

// Early calls are OK - the proxy queues them
const early = await appifio_client.appifio_readFile('contacts.json')
❌ Wrong - do not
  • typeof appifio_client === 'undefined' - the getter always exists; this check is useless
  • if (appifio_client.appifio_readFile) to know “ready” - the proxy always returns a fake function → always truthy even before load
  • Polling loops on appifio_readFile - use waitForAppStorage() instead

Deferred DOMContentLoaded: if you register a listener after bootstrap, the system still keeps the queue until the client is ready and the DOM is ready - code inside the listener can safely call the API.

5. Global helper functions

FunctionBehavior
waitForAppStorage()Promise - resolves when the real client is ready (already ready → resolves immediately)
onAppStorageReady(cb)Calls cb(client) - sync if ready, otherwise after load
withClient(async (client) => …)Loads the client then runs the callback with the real instance
getAppStorageClient() / getClient()Returns instance or proxy (may still be the proxy)
initAppStorage()Alias of loadAppStorageClient() - rarely call by hand

Event:

window.addEventListener('appStorageClientReady', (e) => {
  const client = e.detail.client
  // client is ready
})

6. Recommended pattern - copy-ready

// Shortest pattern - every app HTML page
document.addEventListener('DOMContentLoaded', async () => {
  await window.waitForAppStorage()
  const list = await appifio_client.appifio_readList('blog.json', ['id', 'title', 'slug'])
  const rows = list.data?.content || []
  // render...
})

// Or use the callback
window.onAppStorageReady(async (client) => {
  await client.appifio_readList('contacts.json', ['id', 'name'])
})

Fallback (page without bootstrap - rare):

try {
  if (typeof window.waitForAppStorage === 'function') {
    await window.waitForAppStorage()
  } else {
    console.warn('AppStorage bootstrap missing - API unavailable')
  }
} catch (error) {
  console.warn('Error waiting for AppStorage:', error)
}

Checklist

  1. Does every page with JS API await waitForAppStorage() first?
  2. No typeof appifio_client === 'undefined'?
  3. No if (appifio_client.appifio_readFile) readiness check?
  4. Dates via AM08, not hand-parsing CMS settings?

Appifio Creator · Method series · AM09