Skip to main content

Game Direct (legacy)

Embed an individual game directly in your web application or mobile app.

Overview​

Game Direct puts one of our daily puzzle formats on your page or in your app, complete with its own post-game experience: a results sheet, the player's streaks and stats, and (when enabled for your account) an archive of past games. You choose a format once, and the embed automatically loads that format's game from your schedule every day.

Compared with the JavaScript SDK and the Direct Endpoint, which load just the game, this embed brings its own surrounding experience and needs no code beyond an iframe or WebView. It serves daily puzzle formats only; mini snacks load through the SDK or /play. Its events use a flat message shape of their own.

Game Direct predates the SDK and the Direct Endpoint. It remains supported for existing integrations; new integrations usually start with the JavaScript SDK.

Implementation Strategies​

Web Applications: Use an iframe embed with proper permissions for clipboard access, sharing functionality, and analytics tracking.

Mobile Applications: Use a WebView component that navigates directly to the game URL, providing a seamless native app experience while leveraging our web-based games.

Setup​

Obtain PARTNER_ID​

You'll need a PARTNER_ID (your partner key) before integrating Lil Snack into your application. The PARTNER_ID is a unique identifier that directs Lil Snack to your specific schedule of daily games. To obtain a PARTNER_ID, please contact support@lilsnack.co.

Select GAME_TYPE​

You'll also need a GAME_TYPE: the ID of the game format you want to embed. Your Lil Snack contact will share the game types enabled for your partner key, and new formats are added regularly. To feature several formats, embed one iframe per game type.

Implementation​

The game URL format is:

https://staging.play.lilsnack.co/embed-game-direct?partner=PARTNER_ID&gt=GAME_TYPE

Replace PARTNER_ID with your provided PARTNER_ID and GAME_TYPE with the game type you want to display.

Web Applications​

For web applications, use an iframe to embed the game directly on your page. The iframe should include proper permissions for full functionality.

HTML/JSX​

<iframe
id="lil-snack-game-direct-embed"
src="https://staging.play.lilsnack.co/embed-game-direct?partner=PARTNER_ID&gt=GAME_TYPE"
style={{
width: "380px",
height: "660px",
border: "none",
borderRadius: 8,
}}
loading="lazy"
scrolling="no"
allowFullScreen
allow="clipboard-read; clipboard-write; web-share; storage-access"
></iframe>

Iframe Permissions Explained​

The allow attribute includes the following permissions to ensure full game functionality:

  • clipboard-read & clipboard-write: Enable copying game results and scores to the clipboard for easy sharing
  • web-share: Enables native share sheets on mobile devices for sharing game results
  • storage-access: Enables access to cookies and localStorage for game state saving and analytics tracking

These permissions ensure that players can share their results, save their progress, and that analytics data is properly collected.

Adjust the iframe dimensions based on your site's layout needs. For responsive designs, consider using percentage-based widths and CSS media queries.

Mobile Applications​

For mobile applications, use a WebView component to load the game URL directly. This provides a native app experience while leveraging our web-based games.

iOS (Swift/SwiftUI)​

import SwiftUI
import WebKit

struct LilSnackGameView: UIViewRepresentable {
let partnerId: String
let gameType: String

func makeUIView(context: Context) -> WKWebView {
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true
config.mediaTypesRequiringUserActionForPlayback = []

// Use the default persistent data store (required for player streak/stats)
config.websiteDataStore = WKWebsiteDataStore.default()

let webView = WKWebView(frame: .zero, configuration: config)
return webView
}

func updateUIView(_ webView: WKWebView, context: Context) {
let urlString = "https://staging.play.lilsnack.co/embed-game-direct?partner=\(partnerId)&gt=\(gameType)"
if let url = URL(string: urlString) {
let request = URLRequest(url: url)
webView.load(request)
}
}
}

// Usage
LilSnackGameView(partnerId: "YOUR_PARTNER_ID", gameType: "GAME_TYPE")

Android (Kotlin)​

import android.webkit.WebView
import android.webkit.WebViewClient
import android.webkit.WebSettings
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView

@Composable
fun LilSnackGameView(partnerId: String, gameType: String) {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
WebView(context).apply {
webViewClient = WebViewClient()
settings.apply {
javaScriptEnabled = true
domStorageEnabled = true // Required for player streak/stats
allowFileAccess = true
allowContentAccess = true
mediaPlaybackRequiresUserGesture = false
}

val url = "https://staging.play.lilsnack.co/embed-game-direct?partner=$partnerId&gt=$gameType"
loadUrl(url)
}
}
)
}

// Usage
LilSnackGameView(partnerId = "YOUR_PARTNER_ID", gameType = "GAME_TYPE")

React Native​

import React from "react";
import { WebView } from "react-native-webview";
import { StyleSheet, View } from "react-native";

const LilSnackGameView = ({ partnerId, gameType }) => {
const gameUrl = `https://staging.play.lilsnack.co/embed-game-direct?partner=${partnerId}&gt=${gameType}`;

return (
<View style={styles.container}>
<WebView
source={{ uri: gameUrl }}
style={styles.webview}
javaScriptEnabled={true}
domStorageEnabled={true}
allowsInlineMediaPlayback={true}
mediaPlaybackRequiresUserAction={false}
/>
</View>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
},
webview: {
flex: 1,
},
});

export default LilSnackGameView;

An example web embed will look something like this:

Partner Embed Example

Data Persistence​

Lil Snack games use local storage to track player streaks and statistics. To ensure this data persists between sessions, your WebView must be configured for persistent storage.

iOS (WKWebView)​

Use the default (persistent) data store, not an ephemeral one:

// Use the default persistent data store
let config = WKWebViewConfiguration()
config.websiteDataStore = WKWebsiteDataStore.default() // Persistent
let webView = WKWebView(frame: .zero, configuration: config)
warning

Avoid using .nonPersistent() as this will cause player data to be lost when the app closes:

// Do NOT use this configuration
config.websiteDataStore = .nonPersistent() // Player data will not persist

Android (WebView)​

Ensure DOM storage is enabled:

webView.settings.domStorageEnabled = true  // Required for localStorage

Avoid setting the WebView to private/incognito mode if you want player data to persist.

What Gets Stored​

The following player data is stored locally:

  • Current streak: consecutive days played
  • Max streak: highest streak achieved
  • Total games played: lifetime count
  • Total wins: lifetime win count
  • Last played game: prevents duplicate plays

What Can Cause Data Loss​

Player statistics will be reset if:

  • The user clears the app's data or cache from device settings
  • The user uninstalls and reinstalls the app
  • The WebView is configured with ephemeral/non-persistent storage
info

This is expected behavior for client-side storage. Players should understand that clearing app data will reset their game statistics.

Deploy​

Once successfully integrated, we will deploy your PARTNER_ID to production. At that time, you'll need to update your implementation to use the production URL.

URL Migration​

Update your base URL from:

https://staging.play.lilsnack.co/embed-game-direct?partner=PARTNER_ID&gt=GAME_TYPE

To:

https://play.lilsnack.co/embed-game-direct?partner=PARTNER_ID&gt=GAME_TYPE

Implementation Updates​

Web Applications: Update the src attribute in your iframe to use the production URL.

Mobile Applications: Update the URL string in your WebView implementation to point to the production endpoint.

warning

The production play.lilsnack.co URL will only work with approved Lil Snack partners. Do not switch to production URLs until your PARTNER_ID has been deployed to production.

Troubleshooting​

Player Data Not Saving​

If players report losing their streak after closing the app:

  1. iOS: Verify you're not using WKWebsiteDataStore.nonPersistent(): use .default() instead
  2. Android: Ensure domStorageEnabled = true in your WebView settings
  3. All platforms: Note that clearing app data/cache from device settings will reset player statistics, which is expected behavior