Getting started
The SDK initializes automatically. There is no init() call. At runtime, Mobile Locker injects authentication via the ?jwt= query parameter on the presentation URL.
1. Import the SDK
Section titled “1. Import the SDK”Bundled presentation (ESM):
import mobilelocker from '@mobilelocker/javascript-sdk'Script tag (UMD): see UMD in presentation HTML — the global is mobilelocker (use mobilelocker.default || mobilelocker).
Named exports are available for TypeScript consumers (user, crm, MobileLockerError, GeneralErrorCode, domain types, …). See src/index.ts / package types.
2. Confirm you are in Mobile Locker (optional)
Section titled “2. Confirm you are in Mobile Locker (optional)”if (!mobilelocker.isMobileLocker()) { console.warn('Not running inside Mobile Locker — bridge calls may no-op')}Top-level helpers on the default export: isMobileLocker, isApp, isIOS, isAndroid, isWindows, isCDN, isElectron. Details: Environments.
3. First success path — greet the user
Section titled “3. First success path — greet the user”import mobilelocker, { MobileLockerError, GeneralErrorCode,} from '@mobilelocker/javascript-sdk'
async function boot() { try { const currentUser = await mobilelocker.user.get() // User fields are snake_case: name, email, current_team_id, … console.log(`Hello, ${currentUser.name}`)
// Optional: gate features on app version (iOS/Android only) if (mobilelocker.isApp()) { const info = await mobilelocker.device.get() if (info) console.log('App version', info.app.version) } } catch (err) { if (err instanceof MobileLockerError) { if (err.code === GeneralErrorCode.NotConnected) { console.warn('Offline — show a banner and retry later') return } console.error('SDK error', err.code, err.message) return } throw err }}
boot()You should see the current user’s name when the presentation runs inside Mobile Locker with a valid session.
4. Common next calls
Section titled “4. Common next calls”| Goal | Start here |
|---|---|
| Query Salesforce / CRM | CRM — crm.query, eachAccountsPage, … |
| Walk the address book | Contacts — contacts.eachPage |
| Scan a badge or business card (iOS) | Scanner |
| Persist presentation data | Storage · localforage |
| Call your own HTTPS API | HTTP — http.get(url), http.post(url, body, options?) |
| Bundled SQLite | Database |
| Open PDF / video | UI |
| Structured logging | Log |
| Full domain map | Domains overview |
| Interactive IVA demo | SDK Demo IVA |
5. Large lists use cursor paging
Section titled “5. Large lists use cursor paging”Contacts and CRM offline lists return a Page<T> cursor envelope (iOS 5.5.0+). Walk page by page — do not load an entire large set into one array.
// Page shape (src/types/page.ts){ data: T[]; meta: { cursor: { next: string | null; count: number } } }// Process one page at a timeawait mobilelocker.contacts.eachPage(500, (chunk) => { for (const contact of chunk) { // render / index this contact }})
// Or manual:const page = await mobilelocker.contacts.getPage(500)// advance only with page.meta.cursor.next until nullPrefer crm.query (SOQL) when you only need a filtered CRM set. Details: Contacts, CRM.
Error handling pattern
Section titled “Error handling pattern”Prefer instanceof MobileLockerError and *ErrorCode constants — see Errors.