Class: Plandalf
This is the ES module class returned by new Plandalf() or init(). The script-tag plandalf object exposes a smaller, intentional public surface. In particular, preload() appears below because it exists on the class, but it is absent from the browser object and the PlandalfSDK interface.
Defined in: packages/sdk/src/core/sdk.ts:213
Plandalf SDK - Main Entry Point
For ES module imports: import { Plandalf, init } from '@plandalf/sdk';
Implements
Constructors
Constructor
new Plandalf(
config?):Plandalf
Defined in: packages/sdk/src/core/sdk.ts:228
Parameters
config?
PlandalfConfig = {}
Returns
Plandalf
Properties
harnesses
harnesses:
object
Defined in: packages/sdk/src/core/sdk.ts:780
get
get: (
id) =>HarnessDefinition
Parameters
id
string
Returns
register
register: (
harness) =>void
Parameters
harness
Returns
void
Implementation of
Methods
addGate()
addGate(
name: string,
flow: string,
check?: GateCheck<any>,
): voidDefined in: packages/sdk/src/core/sdk.ts:376
Register a gate. A gate wraps a feature behind an access check. If the check fails (or is absent), the SDK presents the linked flow.
plandalf.addGate("export", "upgrade", () => user.plan !== "free") plandalf.addGate("course", "buy-course") // no check = always presents
Parameters
name
string
flow
string
check?
GateCheck<any>
Returns
void
Implementation of
configure()
configure(config: Partial<PlandalfConfig>)Defined in: packages/sdk/src/core/sdk.ts:806
Parameters
config
Partial<PlandalfConfig>
Returns
Plandalf
gate()
async gate(
name: string,
sync?: GateSyncCallback,
options?: Partial<FlowOpenOptions>,
): Promise<GateResult>Defined in: packages/sdk/src/core/sdk.ts:396
Check a gate. If the check passes, resolves immediately with access: true. If it fails, presents the linked flow. After completion, sync returns fresh entitlements and the same check runs again with those values. Check/sync failures deny access without opening another checkout.
Parameters
name
string
sync?
options?
Partial<FlowOpenOptions>
Returns
Promise<GateResult>
Example
import { Plandalf } from '@plandalf/sdk'
declare function readAccessFromServer(): Promise<{ canExport: boolean }>
const sdk = new Plandalf({
apiBase: 'https://your-org.plandalf.dev',
})
let access = await readAccessFromServer()
sdk.addGate('export', 'upgrade', (fresh) =>
(fresh as typeof access | undefined)?.canExport ?? access.canExport,
)
const result = await sdk.gate('export', async () => {
access = await readAccessFromServer()
return access
})
if (result.access) {
// Your server must enforce access again for the protected action.
}The sync callback is your application's code. The returned browser result is useful for UI state; enforce the entitlement on your server. Read the gate guide.
Implementation of
getAnonId()
getAnonId(): stringDefined in: packages/sdk/src/core/sdk.ts:330
Get the anonymous device ID. Always present — generated on first visit, persists forever. Use this to track anonymous visitors and link them to identified users later.
Returns
string
Implementation of
getIdentity()
getIdentity(): VisitorIdentityDefined in: packages/sdk/src/core/sdk.ts:338
Get the full visitor identity record. Contains anonymous_id, ref, first_seen_at, last_seen_at.
Returns
getRef()
getRef(): string | nullDefined in: packages/sdk/src/core/sdk.ts:345
Get the visitor ref (external identity from ?pf_ref=), or null.
Returns
string | null
getSessionAge()
getSessionAge(): numberDefined in: packages/sdk/src/core/sdk.ts:361
Get seconds elapsed since this visitor first arrived (first_seen_at).
Returns
number
getUserToken()
getUserToken(): string | nullDefined in: packages/sdk/src/core/sdk.ts:321
Get the current user token, or null if anonymous.
Returns
string | null
identify()
identify(token: string): voidDefined in: packages/sdk/src/core/sdk.ts:296
Identify the current user. Accepts a JWT (signed with your API key) or a plain email string.
The token is persisted to localStorage and restored on page reload. It's sent on all subsequent API calls (Authorization header). The anonymous ID is also sent (X-Plandalf-Anon header) so the backend can link anonymous sessions to this user.
plandalf.identify("eyJhbGciOiJIUzI1NiJ9...") // JWT plandalf.identify("jane@acme.com") // email
Parameters
token
string
Returns
void
Implementation of
mount()
mount(
target: HTMLElement | string,
slug: string,
opts: MountOptions = {},
): FlowHandle<Flow>Defined in: packages/sdk/src/core/sdk.ts:602
Mount an offer inline. Mirrors present() but renders into the merchant's
own container instead of a frame.
opts.promo accepts a plain promo slug — the SDK resolves the active tier
internally and applies its tier price to the cart. Refs come from the
existing identity record (auto-captured from ?pf_ref= on init).
Parameters
target
string | HTMLElement
slug
string
opts?
MountOptions = {}
Returns
Example
import { Plandalf } from '@plandalf/sdk'
const sdk = new Plandalf({
apiBase: 'https://your-org.plandalf.dev',
})
const target = document.querySelector<HTMLElement>('#checkout')
if (!target) throw new Error('Checkout container is missing')
const flow = await sdk.mount(target, 'pro-plan')The handle resolves when the Flow is mounted. It does not resolve to the final payment outcome.
Implementation of
preload()
preload(...moduleNames: Array<'checkout'>)Defined in: packages/sdk/src/core/sdk.ts:801
Parameters
moduleNames
..."checkout"[]
Returns
Plandalf
Surface note
This method exists on an ES module Plandalf instance and accepts only 'checkout'. It is not exposed on the browser plandalf object or declared in the PlandalfSDK interface. present() and mount() already load checkout when needed.
import { Plandalf } from '@plandalf/sdk'
const sdk = new Plandalf()
sdk.preload('checkout')present()
present(
slug: string,
options: Partial<FlowOpenOptions> = {},
): FlowHandle<FlowResult>Defined in: packages/sdk/src/core/sdk.ts:450
Present a flow and wait for it to finish.
Always resolves with a FlowResult describing the outcome. Only real errors (network failure, bad slug, etc.) reject. User-supplied onComplete/onClose/onError callbacks still fire.
Parameters
slug
string
options?
Partial<FlowOpenOptions> = {}
Returns
Example
import { Plandalf } from '@plandalf/sdk'
const sdk = new Plandalf({
apiBase: 'https://your-org.plandalf.dev',
})
const result = await sdk.present('upgrade', { frame: 'modal' })
if (result.status === 'complete') {
// Refresh access from your server before unlocking a feature.
}present() returns an awaitable FlowHandle. A dismissal resolves with status: 'dismissed'; genuine loading or session errors reject. See the complete flow.
Implementation of
promo()
promo(slug: string, options?: PromoHandleOptions): PromoHandleDefined in: packages/sdk/src/core/sdk.ts:712
Open a live promo handle. Single entry point for everything promo-related on a host page.
Default behaviour auto-redirects the page to the active tier's
redirect_url when the current URL doesn't match (covers both
tier-rolled-while-here AND arrived-on-stale-URL). Pass
{ redirect: false } to disable the side effect and use the
handle as a pure listener.
Skipped while a Plandalf checkout frame is open — the in-frame countdown reloads the iframe; we don't yank the host page. One promo per page is the canonical pattern; the SDK dedupes by slug.
DOM attach: every element on the page that names this slug via
data-plandalf-promo="<slug>" or data-plandalf-apply-promo="<slug>"
is registered against the handle. So plandalf.from(el) returns
the same handle for any of them, and plandalf:tier-change /
plandalf:expired bubble as DOM CustomEvents on each.
Parameters
slug
string
options?
Returns
Example
import { Plandalf } from '@plandalf/sdk'
const sdk = new Plandalf({
apiBase: 'https://your-org.plandalf.dev',
})
const monitor = sdk.promo('early-bird', { redirect: false })
const state = await monitor
console.log(state?.activeTier?.label, state?.remaining)
monitor.close()The returned PromoHandle is awaitable and also exposes live .events. Close it when you stop monitoring.
Implementation of
reset()
reset(): voidDefined in: packages/sdk/src/core/sdk.ts:306
Clear the current user identity. The anonymous device ID is preserved — only the user token is removed. Next gate/present call will be anonymous.
Returns
void
Implementation of
resetUser()
resetUser():
void
Defined in: packages/sdk/src/core/sdk.ts:316
Returns
void
Deprecated
Use reset(). Retained as an alias during the migration.
setRef()
setRef(ref: string | null): voidDefined in: packages/sdk/src/core/sdk.ts:354
Set the visitor ref and persist it. Call this once you know who the visitor is (email after opt-in, CRM id after login). Survives reloads and future sessions on the same browser.
Parameters
ref
string | null
Returns
void
setUser()
setUser(
token):void
Defined in: packages/sdk/src/core/sdk.ts:313
Parameters
token
string
Returns
void
Deprecated
Use identify(). Retained as an alias during the migration.