Sesamy JS
The official Sesamy browser JavaScript library (@sesamy/sesamy-js) for handling authentication, analytics, content access, and communication with the Sesamy API.
Difference from Sesamy SDK
This is the browser-focused library for content access control and user experience features. For direct API access in Node.js or server environments, use the Sesamy SDK instead.
Installation
Easiest Setup: Scripts Host
For the simplest integration with automatic configuration and updates, use the Scripts Host service instead of manual installation.
npm install @sesamy/sesamy-jsyarn add @sesamy/sesamy-jspnpm add @sesamy/sesamy-jsRequirements
- Modern browser with JavaScript enabled
- TypeScript 4.5+ (for TypeScript projects)
Quick Start
Recommended: Scripts Host
For production use, we recommend using the Scripts Host for automatic configuration and CDN delivery. The examples below show manual integration.
Script Tag Initialization
The simplest way to use the SDK is via a script tag with JSON configuration:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.sesamy.com/sesamy-js/latest/sesamy-js.min.js"></script>
<script type="application/json" id="sesamy-js">
{
"clientId": "your-client-id"
}
</script>
</head>
<body>
<script>
// Wait for the SDK to be ready
window.addEventListener('sesamyJsReady', async () => {
// Check if user is authenticated
const isAuth = await window.sesamy.auth.isAuthenticated();
console.log('User authenticated:', isAuth);
// Get user profile
if (isAuth) {
const profile = await window.sesamy.profile.get();
console.log('User profile:', profile);
}
});
</script>
</body>
</html>Programmatic Initialization
You can also initialize the SDK programmatically:
import { init } from '@sesamy/sesamy-js';
import { createAuth0Plugin } from '@sesamy/sesamy-js/auth0-plugin';
const sesamy = await init(
{ clientId: 'your-client-id' },
{ authPlugin: createAuth0Plugin() }, // omit for BFF / cookie-based auth
);
// Check authentication
const isAuth = await sesamy.auth.isAuthenticated();
// Get user profile
if (isAuth) {
const profile = await sesamy.profile.get();
}Configuration
Basic Configuration
The only required configuration is the clientId:
{
"clientId": "your-client-id"
}Advanced Configuration
{
clientId: "your-client-id",
organization: "org_123", // Optional: Auth0 organization ID
// API configuration
api: {
namespace: "sesamy", // Window object namespace (default: "sesamy")
// Accepts an absolute URL or a relative path on the current origin:
// "https://api2.sesamy.com" – direct / custom domain
// "/api" – proxied through your own backend
endpoint: "https://api2.sesamy.com"
},
// Analytics configuration
analytics: {
enabled: true,
endpoint: "https://logs.sesamy.com/events"
},
// Authentication configuration
auth: {
clientId: "your-client-id",
organization: "org_123",
enabled: true,
domain: "auth.example.com", // Optional: Custom Auth0 domain
domains: [] // Optional: Array of auth domains for multi-domain setups
},
// Content configuration
content: [
{
type: "article",
path: "/articles", // Optional: URL path filter
queryParam: { key: "preview", value: "true" }, // Optional: Query parameter filter
headers: { name: "User-Agent", contains: "mobile" }, // Optional: Header filter (case-insensitive)
pass: "premium", // Optional: Pass requirement
price: {
amount: 9.99,
currency: "USD"
},
paywallUrl: "https://example.com/paywall",
enablePaywallSettingsUrlFallback: false, // Optional: Fallback to <sesamy-paywall settings-url>
selectors: {
article: { selector: "article" },
title: { selector: "h1", attribute: "textContent" },
image: { selector: "img", attribute: "src" },
// ... other selectors
}
}
],
// Transform configuration
transforms: {
enabled: false,
rules: []
}
}Multi-Domain Authentication
For applications across multiple domains (white-label, multi-region):
{
auth: {
clientId: "your-client-id",
domains: [
"auth.brand1.com",
"auth.brand2.com",
"auth.example.co.uk"
],
domain: "default-auth.example.com" // Fallback domain
}
}The SDK automatically selects the appropriate auth domain based on the current page's top-level domain.
Cookie-Based (BFF) Authentication
For publishers deploying on a custom domain, sesamy-js supports the Token Handler pattern where the Sesamy API proxy manages the OAuth flow and stores tokens in HttpOnly cookies. JavaScript never sees a raw access token.
When to use this
Use useHttpCookies: true when your site is served from a custom domain behind the Sesamy API proxy (configured via Scripts Host). It is the recommended option for paywalls and premium content sites.
How auth mode is selected
sesamy-js chooses its auth plugin at startup:
- If
authPluginis passed toinit()as the second argument → use it (explicit and preferred). - If
auth.useHttpCookies: trueis set → use the cookie-based BFF plugin regardless of what else is present. - If the Auth0 plugin IIFE was loaded as a
<script>before sesamy-js → detected automatically via thewindow.auth0Pluginglobal. - Otherwise → fall back to the cookie-based BFF plugin.
Setting auth.useHttpCookies: true is the explicit, unambiguous way to opt in. It makes the cookie plugin redirect login() to /auth/{vendorId}/login (and logout() to /auth/logout) instead of opening the Auth0 Universal Login popup/redirect.
The api.endpoint field controls where sesamy-js sends data API requests (/entitlements, /contracts, etc.) and accepts either a relative path or a full URL. It does not affect the /auth/* routes — those are always relative to the current origin:
Relative path (proxy on same origin)
Set api.endpoint to a path such as "/api" when your backend proxies Sesamy API routes under that prefix:
{
"clientId": "your-vendor-id",
"vendorId": "your-vendor-id",
"auth": {
"useHttpCookies": true
},
"api": {
"endpoint": "/api"
}
}All API calls (/api/entitlements, /api/contracts, etc.) are made to the same origin as the page, so HttpOnly cookies are sent automatically.
Custom domain
Set api.endpoint to a fully-qualified URL when your Sesamy API proxy lives on a dedicated subdomain:
{
"clientId": "your-vendor-id",
"vendorId": "your-vendor-id",
"auth": {
"useHttpCookies": true
},
"api": {
"endpoint": "https://api.yoursite.com"
}
}The @auth0/auth0-spa-js script is not required in either mode.
Login & Logout
In BFF mode the SDK's login() method navigates to /auth/{vendorId}/login (vendor ID comes from your vendorId / clientId config). The logout() method navigates to /auth/logout:
// Trigger login (redirects to token.sesamy.com via /auth/<vendorId>/login, then back)
await window.sesamy.auth.login();
// Trigger logout
await window.sesamy.auth.logout();Auth Status
The SDK automatically checks auth status on load by calling /auth/userinfo. You can also check it manually:
const isAuth = await window.sesamy.auth.isAuthenticated();Local Development with Vite
When developing locally, you need a reverse proxy so browser cookies are scoped to localhost. Configure Vite to forward /auth and API routes to the Sesamy API proxy:
// vite.config.ts
import { defineConfig } from 'vite';
const API_TARGET = process.env.VITE_API_TARGET ?? 'https://api2.sesamy.dev';
const FORWARDED_HOST = process.env.VITE_FORWARDED_HOST ?? 'localhost:5173';
function apiProxy() {
return {
target: API_TARGET,
changeOrigin: true,
headers: {
// Tells the Worker which hostname to use for cookie scoping
// and token-handler lookup. Must match the entry in your
// token-handler config (auth_hostname).
'x-forwarded-host': FORWARDED_HOST,
},
};
}
export default defineConfig({
server: {
proxy: {
// Forward /auth/* for the BFF token-handler flow
'/auth': apiProxy(),
// If using a prefix like api.endpoint = "/api", a single rule covers
// all Sesamy API routes. Otherwise list each route individually.
'/api': apiProxy(),
// Example: individual routes when not using a prefix
// '/contracts': apiProxy(),
// '/entitlements': apiProxy(),
// '/products': apiProxy(),
// '/profile': apiProxy(),
},
},
});Using a local API Worker instead
To run the API Worker locally (e.g. wrangler dev --remote on port 8787) instead of forwarding to the deployed dev API:
VITE_API_TARGET=http://localhost:8787 pnpm devBecause login and callback URLs now include the vendor ID in the path (/auth/<vendorId>/login), cookie scoping no longer depends on x-forwarded-host. You can navigate directly to http://localhost:8787/auth/<vendorId>/login and the full BFF flow will work. Remember to add http://localhost:8787/auth/<vendorId>/callback to the Allowed Callback URLs in your Auth0 application settings.
Deployed API target and localhost cookies
When VITE_API_TARGET points to the deployed api2.sesamy.dev Worker (the default), cookies set by that Worker will be scoped to .sesamy.dev — not localhost — and won't be sent back by your browser. For a fully working BFF flow in local development, use a local wrangler dev instance (VITE_API_TARGET=http://localhost:8787) or navigate directly to http://localhost:8787/auth/<vendorId>/login without the Vite proxy.
Core API
Safely Accessing the API
When building components or modules that need to access Sesamy JS, use this helper function to safely wait for the SDK to be ready:
export async function getApi(): Promise<SesamyAPI> {
// If already ready, return immediately
if (window.sesamy?.isReady()) {
return window.sesamy;
}
// Wait for the ready event with timeout
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
window.removeEventListener('sesamyJsReady', onSesamyJsReady);
if (window.sesamy) {
resolve(window.sesamy);
} else {
reject(new Error('sesamyJsReady event did not occur within the expected time.'));
}
}, 5000);
function onSesamyJsReady() {
if (!window.sesamy) {
reject(new Error('Sesamy API is not available'));
} else {
clearTimeout(timeout);
window.removeEventListener('sesamyJsReady', onSesamyJsReady);
resolve(window.sesamy);
}
}
window.addEventListener('sesamyJsReady', onSesamyJsReady);
});
}Usage:
// In your component or module
async function initComponent() {
try {
const sesamy = await getApi();
// Now safely use the API
const isAuth = await sesamy.auth.isAuthenticated();
if (isAuth) {
const profile = await sesamy.profile.get();
console.log('User profile:', profile);
}
} catch (error) {
console.error('Failed to initialize Sesamy:', error);
}
}
initComponent();This approach:
- Returns immediately if the SDK is already ready
- Waits for the
sesamyJsReadyevent if not ready yet - Includes a 5-second timeout to prevent hanging
- Properly cleans up event listeners
Checking SDK Readiness
For simple synchronous checks:
// Check if SDK is ready
if (window.sesamy?.isReady()) {
console.log('SDK is ready');
}
// Or listen for the ready event
window.addEventListener('sesamyJsReady', () => {
console.log('SDK is ready');
});API Documentation
Sesamy JS provides a comprehensive set of APIs organized by functionality:
Authentication
User login, logout, session management, and profile operations. Authentication is separate because it's fundamental to all other operations.
Content
Content discovery, access control, paywalls, and content unlocking. This is a distinct browser-specific feature for managing locked content.
API Reference
Complete API reference for all SDK wrapper methods:
- Entitlements - Check and manage user access to content
- Subscriptions (Contracts) - Manage user subscriptions
- Checkouts - Create and manage purchase flows
- Products - Retrieve product information
- Bills & Transactions - Access billing history
- Attribution - Manage tracking attribution
These are grouped together as they're all SDK wrapper methods providing similar functionality.
Analytics
Event tracking and analytics. Separate because it's an optional feature that can be enabled/disabled independently.
TypeScript Support
The library includes comprehensive TypeScript definitions:
import { init, SesamyAPI } from '@sesamy/sesamy-js';
const sesamy: SesamyAPI = await init({
clientId: 'your-client-id',
});
// Full type safety
const profile: Profile | null = await sesamy.profile.get();
const entitlements: Entitlement[] = await sesamy.entitlements.list();Next Steps
- Authentication Guide - Learn about login flows and user management
- BFF / Cookie Authentication - Secure token storage via HttpOnly cookies
- Content Management - Set up paywalls and locked content
- API Reference - Complete API documentation for all methods
- Scripts Host API - Use the CDN for automatic configuration