Skip to content
This repository was archived by the owner on Feb 15, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions src/Lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,108 @@ export class Lib {
this.cachedData = null
}

/**
* Gets the anonymous profile ID for the current visitor.
* If profileId was set via init options, returns that.
* Otherwise, requests server to generate one from IP/UA hash.
*
* This ID can be used for revenue attribution with payment providers.
*
* @returns A promise that resolves to the profile ID string, or null on error.
*
* @example
* ```typescript
* const profileId = await swetrix.getProfileId()
*
* // Pass to Paddle Checkout for revenue attribution
* Paddle.Checkout.open({
* items: [{ priceId: 'pri_01234567890', quantity: 1 }],
* customData: {
* swetrix_profile_id: profileId,
* swetrix_session_id: await swetrix.getSessionId()
* }
* })
* ```
*/
async getProfileId(): Promise<string | null> {
// If profileId is already set in options, return it
if (this.options?.profileId) {
return this.options.profileId
}

if (!isInBrowser()) {
return null
}

try {
const apiBase = this.getApiBase()
const response = await fetch(`${apiBase}/log/profile-id`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ pid: this.projectID }),
})

if (!response.ok) {
return null
}

const data = (await response.json()) as { profileId: string | null }
return data.profileId
} catch {
return null
}
}

/**
* Gets the current session ID for the visitor.
* Session IDs are generated server-side based on IP and user agent.
*
* This ID can be used for revenue attribution with payment providers.
*
* @returns A promise that resolves to the session ID string, or null on error.
*
* @example
* ```typescript
* const sessionId = await swetrix.getSessionId()
*
* // Pass to Paddle Checkout for revenue attribution
* Paddle.Checkout.open({
* items: [{ priceId: 'pri_01234567890', quantity: 1 }],
* customData: {
* swetrix_profile_id: await swetrix.getProfileId(),
* swetrix_session_id: sessionId
* }
* })
* ```
*/
async getSessionId(): Promise<string | null> {
if (!isInBrowser()) {
return null
}

try {
const apiBase = this.getApiBase()
const response = await fetch(`${apiBase}/log/session-id`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ pid: this.projectID }),
})

if (!response.ok) {
return null
}

const data = (await response.json()) as { sessionId: string | null }
return data.sessionId
} catch {
return null
}
}

/**
* Gets the API base URL (without /log suffix).
*/
Expand Down
57 changes: 57 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,63 @@ export function clearExperimentsCache(): void {
LIB_INSTANCE.clearExperimentsCache()
}

/**
* Gets the anonymous profile ID for the current visitor.
* If profileId was set via init options, returns that.
* Otherwise, requests server to generate one from IP/UA hash.
*
* This ID can be used for revenue attribution with payment providers like Paddle.
*
* @returns A promise that resolves to the profile ID string, or null on error.
*
* @example
* ```typescript
* const profileId = await getProfileId()
*
* // Pass to Paddle Checkout for revenue attribution
* Paddle.Checkout.open({
* items: [{ priceId: 'pri_01234567890', quantity: 1 }],
* customData: {
* swetrix_profile_id: profileId,
* swetrix_session_id: await getSessionId()
* }
* })
* ```
*/
export async function getProfileId(): Promise<string | null> {
if (!LIB_INSTANCE) return null

return LIB_INSTANCE.getProfileId()
}

/**
* Gets the current session ID for the visitor.
* Session IDs are generated server-side based on IP and user agent.
*
* This ID can be used for revenue attribution with payment providers like Paddle.
*
* @returns A promise that resolves to the session ID string, or null on error.
*
* @example
* ```typescript
* const sessionId = await getSessionId()
*
* // Pass to Paddle Checkout for revenue attribution
* Paddle.Checkout.open({
* items: [{ priceId: 'pri_01234567890', quantity: 1 }],
* customData: {
* swetrix_profile_id: await getProfileId(),
* swetrix_session_id: sessionId
* }
* })
* ```
*/
export async function getSessionId(): Promise<string | null> {
if (!LIB_INSTANCE) return null

return LIB_INSTANCE.getSessionId()
}

export {
LibOptions,
TrackEventOptions,
Expand Down