State SDK
Save and retrieve user data, game progress, preferences, and more — without setting up a backend server.
Download for Your AI Tool
Download this guide and paste it into Google AI Studio, Lovable, Cursor, Claude, ChatGPT, or any AI coding tool to let them use state management in your app.
Download Guide (.md)Quick Start
The SDK is automatically injected into your app and accessible via window.gapp.state.
// Save data
await gapp.state.set('theme', 'dark')
// Read data
const theme = await gapp.state.get('theme')
console.log(theme) // 'dark'
// Delete data
await gapp.state.delete('theme')State Scopes
The SDK supports three state scopes for different use cases.
| Scope | Purpose | Who Can Access |
|---|---|---|
Default | Auto-select (logged-in = user, anonymous = session) | Current user/device |
user | Logged-in user's personal data, synced across devices | Only that user |
session | Anonymous user's device-bound data | Only that device |
global | Data shared by all users (e.g., leaderboards) | Everyone can read |
API Reference
Basic Operations
Auto-selects scope based on auth status
gapp.state.set(key, value)Save data (user scope if logged in, session if anonymous)
await gapp.state.set('theme', 'dark')gapp.state.get(key)Read data
const theme = await gapp.state.get('theme')gapp.state.delete(key)Delete data
await gapp.state.delete('theme')gapp.state.list()List all keys
const keys = await gapp.state.list()
User Scope
Requires login, syncs across devices
gapp.state.user.set(key, value)Save to user scope
await gapp.state.user.set('preferences', { theme: 'dark' })gapp.state.user.get(key)Read from user scope
const prefs = await gapp.state.user.get('preferences')Session Scope
Device-bound, works for anonymous users
gapp.state.session.set(key, value)Save to session scope
await gapp.state.session.set('tempData', { draft: '...' })gapp.state.session.get(key)Read from session scope
const temp = await gapp.state.session.get('tempData')Global Scope
Shared by all users of the app
gapp.state.global.get(key)Read global data
const leaderboard = await gapp.state.global.get('leaderboard')gapp.state.global.set(key, value)Write global data
await gapp.state.global.set('leaderboard', scores)Utility Methods
Helper functions
gapp.state.isAuthenticated()Check if user is logged in
if (gapp.state.isAuthenticated()) { /* user logged in */ }gapp.state.migrateSessionToUser()Migrate anonymous data to logged-in account
await gapp.state.migrateSessionToUser()
Usage Examples
User Preferences
// Load preferences
async function loadPreferences() {
const prefs = await gapp.state.get('preferences') || {
theme: 'light',
fontSize: 14,
notifications: true
}
applyPreferences(prefs)
}
// Save preferences
async function savePreferences(prefs) {
await gapp.state.set('preferences', prefs)
}Game Progress
// Save game progress
async function saveGame() {
const gameState = {
level: currentLevel,
score: playerScore,
inventory: playerInventory,
timestamp: Date.now()
}
await gapp.state.set('saveGame', gameState)
showMessage('Game saved!')
}
// Load game progress
async function loadGame() {
const saved = await gapp.state.get('saveGame')
if (saved) {
restoreGameState(saved)
} else {
startNewGame()
}
}Global Leaderboard
// Submit score
async function submitScore(playerName, score) {
const leaderboard = await gapp.state.global.get('leaderboard') || []
leaderboard.push({
name: playerName,
score: score,
date: new Date().toISOString()
})
// Sort and keep top 100
leaderboard.sort((a, b) => b.score - a.score)
const top100 = leaderboard.slice(0, 100)
await gapp.state.global.set('leaderboard', top100)
}
// Display leaderboard
async function showLeaderboard() {
const leaderboard = await gapp.state.global.get('leaderboard') || []
renderLeaderboard(leaderboard)
}Limits
| Limit | Value |
|---|---|
| Max key length | 100 characters |
| Allowed key characters | a-z, A-Z, 0-9, _, - |
| User/Session data limit | 100 KB per app |
| Global data limit | 1 MB per app |
| Max key count | 100 keys per scope |
FAQ
Q: Will anonymous user data be lost?
A: No. Anonymous data is saved on the server, bound to a device ID (stored in localStorage). As long as browser data isn't cleared, data is kept for 90 days. After logging in, users can migrate anonymous data to their account.
Q: Is the data secure?
A: User scope: Only the logged-in user can access. Session scope: Only the same device can access. Global scope: Everyone can read/write based on app creator's settings.
Q: How do I know if the SDK is ready?
A: Listen for the 'gapp:state:ready' event, or just call the API directly (SDK is usually injected when page loads).
Q: Can I use this SDK outside of iframe?
A: No. The State SDK is only available in apps hosted on gapp.so. If you need external access, use the REST API.