One script tag gives your game login and analytics. A second package gives it cloud saves.
What you get
<script src="https://indie.fun/js/indie.js"></script>
<script>
const indie = new Indie({ appId: 'your-app-id' });
</script>That single line mounts the login widget and starts measuring sessions. Analytics needs no further setup. From npm instead:
npm install indie-sdk
import { IndieClient } from 'indie-sdk/browser';
const indie = new IndieClient({ appId: 'your-app-id' });Publishing on a portal, or a site with its own accounts?
On CrazyGames, Poki or your own site with its own sign-in, our login popup is no use to you and the pill would be a second account system on the screen. Passlogin: false and keep everything else: sessions, session length, frame rate, progression and crash reports are all recorded for players who never sign in. Analytics has the whole setup.Only needed for cloud saves and for reacting to logins on your own game server.
const { Indie } = require('indie-sdk/server');
const indie = new Indie({
appId: 'your-app-id',
appSecret: process.env.INDIE_APP_SECRET,
});
indie.on('playerJoin', (player) => {
console.log(player.id); // unique player id
console.log(player.name); // display name
console.log(player.data); // saved data (already loaded)
console.log(player.permissions); // { chat: true, vip: false }
});
// Save player data any time
indie.savePlayerData(player.id, { highScore: 9001 });Check it worked
Open the sandbox with your App ID. It loads the real SDK, sends real events, and tells you which ones we received, usually within a second or two.
Then open your own game and watch the same checklist under Settings → Setup on your game's page. Every line there is something we actually received, so nothing reads as “working” until it genuinely is.
From your game's own console, the same check by hand:
// in the page where you created the client
await fetch('https://indie.fun/api/sdk/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
appId: indie.getAppId(),
sessionId: indie.getSessionId(),
deviceId: indie.getDeviceId(),
}),
}).then(r => r.json()).then(console.log);
// { app: { exists: true, active: true },
// session: { startedAt: '...', durationSec: 0, identity: 'device' }, ... }session: null means nothing arrived. Check the App ID, and check the browser console for a blocked request. Full details in the API reference.