·5 min read

Make Your App Remember Things with the State SDK

Save user data, game progress, and preferences across sessions — no backend needed. Just tell your AI assistant to use the State SDK.

tutorialstate-sdkdata

The Problem: Everything Resets

You built a great app with AI. A quiz, a game, a tool. Someone uses it, has a great time — then closes the tab. When they come back, everything is gone. High score? Gone. Preferences? Gone. That essay they were writing? Gone.

That's how web apps work by default. But it doesn't have to be that way.


The Fix: gapp.so's State SDK

Every app on gapp.so gets a built-in cloud storage system — no backend setup, no database, no API keys. Your app can save and load data with a few lines of code.

The SDK is automatically available in your app as gapp.state. You don't need to install anything.


How to Add It to Your App

Copy this and send it to your AI coding assistant (Claude Code, Cursor, Gemini, etc.):

> "Use gapp.so's state SDK to save and load user data in my app. Here are the docs: https://gapp.so/ai-sdk-prompt.md"

That's it. Your AI assistant will read the documentation and wire everything up for you.

If you want to be more specific, here are some things you can ask for:

  • *"Save user preferences so they persist across sessions"*
  • *"Add a high score system that remembers each user's best score"*
  • *"Auto-save the user's work every few seconds"*
  • *"Add a global leaderboard that all users can see"*

What Can It Do?

Save Per-User Data

Each user gets their own private storage. Perfect for:

  • Preferences — theme, language, font size
  • Progress — game saves, completed levels, unlocked achievements
  • Personal content — drafts, notes, custom settings
// Save
await gapp.state.set('preferences', { theme: 'dark', lang: 'zh' })

// Load
const prefs = await gapp.state.get('preferences')

Share Data Across All Users

Need a leaderboard? A shared counter? A collaborative space? Use the global scope:

// Read the leaderboard
const scores = await gapp.state.global.get('leaderboard') || []

// Add a new score
scores.push({ name: 'Player1', score: 9500 })
scores.sort((a, b) => b.score - a.score)
await gapp.state.global.set('leaderboard', scores.slice(0, 100))

Auto-Save with Zero Effort

Here's the easiest option: if your app already uses localStorage (and your AI assistant probably made it that way), gapp.so automatically syncs it to the cloud. Your users' data follows them across devices — and you don't need to change a single line of code.

// This already works — gapp.so syncs it automatically
localStorage.setItem('gameProgress', JSON.stringify(progress))

Three Storage Scopes

ScopeWho Can AccessBest For
UserOnly that logged-in user, works across devicesPreferences, saves, personal data
SessionOnly that device (anonymous users)Temporary state, drafts before login
GlobalEveryone using the appLeaderboards, shared content, counters

By default, the SDK auto-selects: logged-in users get user scope, anonymous users get session scope. You don't need to think about it unless you want to.


Real Examples

A Quiz App That Tracks Progress

window.addEventListener('gapp:ready', async () => {
  // Load where the user left off
  const progress = await gapp.state.get('quizProgress') || {
    currentQuestion: 0,
    correctAnswers: 0,
    totalAnswered: 0
  }
  startQuiz(progress)
})

// After each answer
async function onAnswer(isCorrect) {
  progress.totalAnswered++
  if (isCorrect) progress.correctAnswers++
  progress.currentQuestion++
  await gapp.state.set('quizProgress', progress)
}

A Drawing App with Auto-Save

// Save canvas every 2 seconds after changes
let saveTimer
canvas.addEventListener('change', () => {
  clearTimeout(saveTimer)
  saveTimer = setTimeout(async () => {
    await gapp.state.set('canvas', canvas.toJSON())
  }, 2000)
})

// Restore on load
const saved = await gapp.state.get('canvas')
if (saved) canvas.loadFromJSON(saved)

Limits

Limit
User/Session storage100 KB per app
Global storage1 MB per app
Max keys100 per scope
Key length100 characters

These limits are generous for most apps. If you're building something that needs more, consider chunking your data across multiple keys.


User Identity

The SDK also gives you access to user info:

if (gapp.user.isAuthenticated()) {
  const name = gapp.user.getName()
  const avatar = gapp.user.getAvatarUrl()
  showWelcome(name, avatar)
}

This is useful for personalizing the experience — showing a welcome message, displaying the user's name on a leaderboard, or customizing the UI.


Test It Locally

Want to test data saving before publishing? Use local development mode:

  1. Get your dev token from Dashboard > Creator Tools
  2. Add the dev script to your HTML
  3. The State SDK works locally with a localStorage-backed mock — same API, no server needed

Details are in the AI SDK prompt docs.


Quick Reference

I want to...Tell my AI assistant...
Save user data*"Use gapp.so's state SDK: https://gapp.so/ai-sdk-prompt.md"*
Add a leaderboard*"Add a global leaderboard using gapp.state.global"*
Auto-save progress*"Auto-save user progress with debouncing using gapp.state"*
Keep localStorage workingNothing — it syncs automatically
Test locally*"Set up gapp.so local dev mode: https://gapp.so/ai-sdk-prompt.md"*

Full Documentation

Ready to share your creation?

Publish your AI-built app and get a landing page in seconds.

Submit Your App