Salsa's browser-side JavaScript library, Salsa.js.
Looking for a guide on how to embed UI?This here is a reference document for the Salsa.js SDK library detailing the functionality that it provides. If you are looking for a walkthrough explaining how to embed Salsa's UI experiences inside of your own application, we recommend starting with our guide on Embedding an Element.
Including Salsa.js
There are two options for including salsa-js in your project
- Load the Salsa.js script from Salsa's CDN (preferred)
- Include salsa-js as an npm package
Loading Salsa.js from CDN
Load the Salsa.js script from Salsa's CDN URL by including a script tag in your web application.
You may want to specify the async or defer attributes of the script tag if you wish to load it asynchronously.
<script type="text/javascript" src="https://js.salsa.dev/v0"></script>Once the Salsa.js script has loaded, you will be able to initialize the library via the Salsa function that is defined on the window.
Leveraging our salsa-js npm package
salsa-js npm packageYou can install our npm package into your node project
npm install @salsa-payroll/salsa-js
You can then leverage the package to instantiate a Salsa instance
import { loadSalsaJs } from "@salsa-payroll/salsa-js";
const salsa = await loadSalsaJs('ck_your-client-key');
Initializing Salsa.js
Create a Salsa instance
Salsa instanceSalsa(clientKey, options?)
Salsa(clientKey, options?)Creates an instance of the Salsa library. The returned object is your entry point to the rest of the Salsa.js SDK.
This is only needed to be done once for the lifespan of your application runtime (browser session).
Method parameters
clientKey REQUIRED String
clientKey REQUIRED StringYour application's Client Key. This is required in order to identify your application to Salsa.
Your Client Key will formatted similar to ck_f0ac...eb6d8.
options optional Object
options optional ObjectInitialization options.
Properties:
| Name | Type | Description |
|---|---|---|
env | 'sandbox' | 'production' | The environment to use, which can be either our Sandbox or Production environment. Defaults to production if not specified. |
Salsa Elements
Salsa.js exposes a set of a powerful modular components that are designed to be easily embedded inside of your own web application to provide a seamless payroll experience. We refer to each of these components as a "Salsa Element", which you can create and interact with as described here.
Create an Element
salsa.elements.create(elementType, options?)
salsa.elements.create(elementType, options?)Creates an instance of an individual Salsa Element.
Method parameters
elementType REQUIRED String
elementType REQUIRED StringThe type of Element being created.
options optional Object
options optional ObjectA set of options to create this SalsaElement instance with.
Properties:
| Name | Type | Description |
|---|---|---|
userToken | String | A User Token created with an access role that has sufficient permissions for the data that the element interacts with. This is required when using elements that require authorization, which almost all do. |
style | Object | Options for customizing the style of the element. See the following properties table. |
allowRequestForPrivilegedAccess | Boolean | Enables the identity-verification step-up flow. When true, an action the user's current role does not grant emits a request-privileged-access event so your app can verify the user and swap in a higher-role token. When false (the default), no step-up path is offered. See Protecting sensitive actions with identity verification. |
options.style properties:
options.style properties:| Name | Type | Description |
|---|---|---|
colorMode | 'light' | 'dark' | 'system' | Controls what color mode will be used when rendering the element. Defaults to When using |
Mount an Element
salsa.elements.mount(salsaElement, domElement)
salsa.elements.mount(salsaElement, domElement)Attaches the SalsaElement to the DOM. The element will be inserted based on the location specified by domElement.
Method parameters
salsaElement REQUIRED SalsaElement
salsaElement REQUIRED SalsaElementThe SalsaElement instance to mount into the DOM.
domElement REQUIRED String
domElement REQUIRED StringThe CSS selector or DOM element where the SalsaElement will be mounted.
Destroy an Element
salsa.elements.destroy(salsaElement)
salsa.elements.destroy(salsaElement)Removes the Element from the DOM and destroys it, additionally cleaning up any open handles and unregistering all listeners.
Method parameters
salsaElement REQUIRED SalsaElement
salsaElement REQUIRED SalsaElementThe SalsaElement instance to destroy.
Updating an Element's auth token
salsaElement.replaceUserToken(newUserToken)
salsaElement.replaceUserToken(newUserToken)Updates the user auth token without need to refresh the element. This is can be useful when you want refresh an expiring token while someone is still using the element, or to enable you to expire the access of an existing element.
For more information on how to issue user tokens see the related documentation on authorization.
Example
const salsaElement = salsa.elements.create('employer-dashboard', {
userToken: USER_TOKEN,
employerId: EMPLOYER_ID
});
const getSalsaUserToken = (timeToLiveInMinutes) => {
// ...
// This function would send a request to the Partner's own API to issue a Salsa user
// token via a backend to backend API call, using the Partner's API Token. The
// Partner's backend will be responsible for determining the appropriate access role
// and corresponding Salsa entity (employers or workers) that their current user has
// access to.
// ...
return userToken;
}
const TIME_TO_LIVE_MINUTES = 5;
// Define the refresh time to be 1 minute before the expiry time (TTL)
const REFRESH_TOKEN_MILLISECONDS = (TIME_TO_LIVE_MINUTES - 1) * 60 * 1000;
// Automatically refresh the user token before the existing token expires
setInterval(async () => {
const newUserToken = getSalsaUserToken(TIME_TO_LIVE_MINUTES);
await salsaElement.replaceUserToken(newUserToken);
}, REFRESH_TOKEN_MILLISECONDS); Cancelling a privileged-access request
salsaElement.cancelRequestForPrivilegedAccess()
salsaElement.cancelRequestForPrivilegedAccess()Closes the verification prompt that Salsa displays after a request-privileged-access event and returns the user to the previous view without changing their token. Call this when the user abandons or fails your verification flow.
Takes no arguments and returns nothing. It has no effect if there is no pending privileged-access request.
Example
salsaElement.on('request-privileged-access', async (event) => {
const verified = await runYourVerificationFlow();
if (!verified) {
salsaElement.cancelRequestForPrivilegedAccess();
return;
}
const token = await createToken({ role: event.recommendedRole });
await salsaElement.replaceUserToken(token);
});Element events
Listening to events is the mechanism through which all communication with an Element instance is provided. The events available will vary from one Element to another based on the particulars of the experience that is encapsulated, but the fundamentals in which you consume events is consistent throughout.
Listen to an event
<SalsaElement>.on(eventName, handler)
<SalsaElement>.on(eventName, handler)The on function is available on every Element and facilitates the registration of event listeners, enabling you to respond to various user interactions or custom events.. This function is designed to be familiar to developers accustomed to the native web elements' approach for for event handling and registering event listeners.
Method parameters
eventName REQUIRED String
eventName REQUIRED StringThe name of the event to listen to.
handler REQUIRED Function
handler REQUIRED Functionhandler(event) => void is the callback function that will be called whenever the event is triggered. When called, it will be passed an event object as its only parameter, of which the properties will vary based on the event being sent.
Example
// Here 'salsaElement' is a Salsa Element instance created via salsa.elements.create(), as above
salsaElement.on('complete', function(event) {
console.log('Element complete event fired!', event);
});Note - multiple event listeners can be attached for the same event by calling on multiple times with the same eventName.
complete event
complete eventThe complete event is triggered when the workflow associated with the Element is completed by the user. This enables you to react to changes in your application's UI when a user is interacting with an embedded Element just as you would in your own native experiences. While this event is available for many Elements, not all Elements encapsulate a user workflow, and so it is not present for all.
Event object properties
| Name | Type | Description |
|---|---|---|
elementType | String | The type of Element that this event was sent for. |
| ... | -- | Other additional properties may be included that are specific to the Element. |
request-privileged-access event
request-privileged-access eventThe request-privileged-access event is triggered when a user attempts an action that their current role does not grant, and the element was created with allowRequestForPrivilegedAccess: true. It is the entry point to the identity-verification step-up flow: your app verifies the user, creates a token at a higher role, and hands it back with replaceUserToken so Salsa can resume the action. If the user abandons or fails verification, call cancelRequestForPrivilegedAccess.
For the full walkthrough, token lifecycle, and role ladder, see Protecting sensitive actions with identity verification.
Event object properties
| Name | Type | Description |
|---|---|---|
action | String | Identifies which protected action the user attempted. See the table of action IDs below. |
recommendedRole | String | The lowest role that satisfies action, in the createUserToken form (e.g. EMPLOYER_SUPER_ADMIN). Optional — omitted when the current user cannot step up (see note below). Create the elevated token at this role. |
possibleRoles | String[] | Every role that would satisfy action, ordered lowest to highest privilege. Optional — omitted alongside recommendedRole. Pick from this list if you want a role other than the recommended one. |
recommendedRoleandpossibleRolesare optionalSalsa omits both role hints when the user has no step-up path — for example a super-admin already at the top of their lane, or an unrecognized role. Check for
recommendedRolebefore creating a token: if it's absent, there is no higher role to elevate to, so show your own message instead of callingreplaceUserToken.
Action IDs
The action field carries one of the following stable, public identifiers:
| Action ID | Description |
|---|---|
download-document | Opening or downloading a document attached to a worker or employer. |
add-employer-bank-account | Adding a new employer bank account. |
add-worker-bank-account | Adding a new worker bank account. |
delete-worker-bank-account | Removing a worker bank account. |
unmask-employer-bank-account-number | Revealing the full account number for an employer bank account. |
unmask-worker-bank-account-number | Revealing the full account number for a worker bank account. |
unmask-government-id | Revealing a worker's full government ID (e.g. SSN/TIN). |
update-worker-government-id | Editing the value of a worker's government ID. |
download-worker-details-report-with-government-ids | Including unmasked government IDs in the Worker Details report download. |
Example
salsaElement.on('request-privileged-access', async (event) => {
// event.action e.g. "unmask-government-id"
// event.recommendedRole e.g. "EMPLOYER_SUPER_ADMIN" (may be undefined)
// event.possibleRoles e.g. ["EMPLOYER_SUPER_ADMIN"] (may be undefined)
if (!event.recommendedRole) {
// No higher role to step up to — show your own messaging.
salsaElement.cancelRequestForPrivilegedAccess();
return;
}
const verified = await runYourVerificationFlow();
if (!verified) {
salsaElement.cancelRequestForPrivilegedAccess();
return;
}
const token = await createToken({ role: event.recommendedRole });
await salsaElement.replaceUserToken(token);
});