SPAs and video players require a slightly different integration from standard page-based websites because there is no full-page reload between content transitions. Frisbii Media supports two approaches depending on how your player or app is structured.
Approach A – External (recommended for most cases)
The SPA or video player does not embed any Frisbii Media functionality itself. Instead:
Before the player renders, your page checks whether the user has access (server-side or via an API call from the page)
If the user has no access, the Frisbii Media checkout runs on the page (not inside the player), exactly as in the standard website checkout
After a successful purchase, the player is rendered
This keeps the player completely decoupled from Frisbii Media. No special configuration is needed.
Follow the standard checkout guides:
Approach B – Embedded (player runs in its own iframe or sandboxed context)
If the player or SPA runs inside its own iframe, or is otherwise isolated from the parent page's JavaScript context, it needs its own Frisbii Media JavaScript SDK instance with a special configuration. The player communicates with Frisbii Media entirely from within its own context.
SDK configuration for embedded mode
⚠️ Deprecated: The script tag below uses the legacy plenigo SDK URL and attributes. This embedded SDK pattern predates the current SDK. If you are building a new integration, use Approach A. If you are maintaining an existing embedded integration, this configuration still works but the SDK path should be updated when the new equivalent is available.
<!-- Load inside the player iframe / sandboxed context -->
<!-- Replace $COMPANY_ID$ with your Frisbii Media Company ID -->
<script type="application/javascript"
src="https://static.plenigo.com/static_resources/javascript/$COMPANY_ID$/plenigo_sdk.min.js"
data-oauth2-access-code="oAuth2Function"
data-payment-check="checkProductAccess"
data-login-status="loginStatus"
data-disable-metered="true"></script>
<script type="application/javascript">
// Start the SDK manually in embedded mode
plenigo.start();
// Called after a successful OAuth2 login — the access code must be exchanged
// for a token server-side
oAuth2Function = function(oAuth2AccessCode) {
// POST oAuth2AccessCode to your backend
// Your backend exchanges it for an access token via the Frisbii Media OAuth2 endpoint
// See: OAuth 2.0 Flow guide
};
// Called by the SDK to check whether the current user has purchased
// the content being played
checkProductAccess = function() {
// Call your backend, which calls Frisbii Media hasAccess
// Return true (has access) or false (no access) to the SDK
};
// Called when the user's login status changes
loginStatus = function(isLoggedIn) {
if (isLoggedIn === true) {
// User is logged in — show the appropriate player state
// e.g. remove a login overlay
} else {
// User is not logged in — show a login prompt or paywall
}
};
</script>
What each callback does
Callback | Triggered when | What to do |
|---|---|---|
| User completes login in the Frisbii Media SSO iframe inside the player | POST the |
| The SDK needs to verify access (e.g. on load, or after a purchase) | Call your backend → |
| The user's login state changes | Update the player UI accordingly (show/hide paywall, overlay, etc.) |
Starting checkout from inside the player
Checkout, login, and registration calls from inside the player iframe are identical to the standard JavaScript SDK calls:
// Start checkout from inside the player
new plenigo.Checkout(purchaseId, { elementId: "plenigoCheckout" }).start();
// Start login
new plenigo.SSO({ elementId: "plenigoLogin" }).login();
If the SDK is loaded only once for the entire page (including the player), the parent page must handle the plenigo.* events identically to how the player would handle them.
Choosing the right approach
Approach A (External) | Approach B (Embedded) | |
|---|---|---|
Player in same page context? | ✅ Yes | ❌ No (own iframe / sandbox) |
New integration? | ✅ Recommended | Use only for legacy setups |
SDK configuration needed? | Standard | Special data attributes |
OAuth2 required? | No (sessions work) | Yes (callback-based) |