Userflow.js Reference

The userflow global object

Once you've installed Userflow.js in your web app, a userflow object will be available globally on window in users' browsers.

userflow.init(token)

Initializes Userflow.js to target your company. Must be called once (per page load) before you make any other call.

Parameter Type Description
token String, required Your Userflow Token, which you can find under Settings.

Example:

userflow.init('bmztslyu5zgujmcvna34mggj44')

userflow.identify(userId, attributes)

Identifies your user with Userflow. You should call this once on any page load where a user is authenticated.

If attributes is set, they will be merged into the user's existing attributes in Userflow. Any attributes you leave out will be left as-is in Userflow.

It's up to you which attributes you want to send to Userflow. The only required argument is userId. Make sure not to send any sensitive data such as passwords. We recommend sending the name and email attributes so you can easily tell users apart in Userflow without relying on IDs only, and signed_up_at, which is often used in flow start conditions.

If the user has any active flows, they will be displayed. If the user matches any flows' start conditions, they may be started.

Parameter Type Description
userId String, required The user's ID in your database.
attributes Object, optional Attributes to update for the user. See how to set attributes below. These attributes can be used in flow content and conditions to personalize the user experience.

Returns a Promise that resolves once the identify call succeeds.

Example of sending the recommended attributes:

userflow.identify('123456', {
  name: 'Jane Smith',
  email: 'jane@example.com',
  signed_up_at: '2019-06-14T16:25:49Z'
})

Minimal example of sending only userId:

userflow.identify('123456')

attributes, if set, should be an object, where keys are attribute names and values are one of the following:

  • Literal values (string, boolean, number) to just set an attribute to the given value.
  • An object, which can contain the following keys (note that exactly one of set, set_once, add, subtract must be set):
    • set: Sets the attribute to this value. This is the same as setting literal values, except this way you can explicitly set the data_type, too.
    • set_once: Sets the attributes to this value, but only if the user doesn't already have a value for this attribute.
    • add: Adds this value to the attribute's current value. If the user does not have the attribute yet, the given number will be added to 0. Only works on number attributes.
    • subtract: Same as add, but subtracts the given number instead. To subtract, you either supply a negative number to add, or a positive number to subtract.
    • data_type: Explicitly tells Userflow what data type to use. Can be one of: string, boolean, number, datetime. You usually don't have to set this, as Userflow will infer the right data type depending on the values you supply.
  • null or undefined will remove the attribute from the user.

Attribute names must consist only of a-z, A-Z, 0-9, underscores, dashes and spaces. We recommend using snake_case everywhere though. Attributes' human-friendly display names (e.g. "Signed Up" for signed_up_at) can also be configured in the Userflow UI.

Example of using all the possible data types (these will all be inferred as expected):

userflow.identify('123456', {
  string: 'Just a string',
  always_true: true,
  always_false: false,
  integer_number: 42,
  decimal_number: 1234.56,
  used_datetime_at: '2019-12-03T12:34:56.123Z'
})

Explicitly setting data_type:

userflow.identify('123456', {
  // This will be consumed as a string, even though its value
  // is a number here
  phone: {set: 12345678, data_type: 'string'}
})

Using set_once:

userflow.identify('123456', {
  coupon_code: {set_once: generate_onetime_coupon_code()}
})

Using add and subtract:

userflow.identify('123456', {
  widget_count: {add: 1},
  total_revenue: {add: 1234.56},
  days_left: {subtract: 1}
})

userflow.identifyAnonymous(attributes)

Same as userflow.identify, except Userflow.js will automatically assign the current user a unique ID. This ID will be stored in the user's localStorage, and will be reused on reloads.

You should only use this for anonymous users, who are not signed into your app. If they are signed in, please use userflow.identify with their real user ID.

Parameter Type Description
attributes Object, optional See userflow.identify

Returns a Promise that resolves once the identify call succeeds.

Example of identifying an anonymous user and tagging them with a custom website_lead attribute, so they can be targeted by flows:

userflow.identifyAnonymous({
  website_lead: true
})

userflow.isIdentified()

Returns true if userflow.identify has been called. false otherwise.

userflow.updateUser(attributes)

Updates attributes for a user that has already been identified with userflow.identify since the last page load.

Use this if you need to update an attribute after some event happens.

The attributes argument takes the exact same format as in userflow.identify.

Example of updating a user's favorite color after they pick it in your UI:

userflow.updateUser({
  favorite_color: 'red'
})

Returns a Promise that resolves once the update succeeds.

userflow.track(eventName, attributes)

Tracks an event related to the currently identified user. userflow.identify must have been called before calling track.

Events can be used to segment and target flows for users.

Parameter Type Description
eventName String, required Name of the event. Examples: subscription_activated, project_created, coworker_invited. See note about event naming below.
attributes Object, optional Attributes for the event.

Returns a Promise that resolves once the track call succeeds.

Minimal example of tracking an event when a user activates their subscription:

userflow.track('subscription_activated')

Example with attributes:

userflow.track('subscription_activated', {
  plan_name: 'plus',
  plan_price: 1234.56
})

Both event names and attribute names must consist only of a-z, A-Z, 0-9, underscores, dashes and spaces. We recommend using snake_case everywhere though. Events and attributes' human-friendly display names (e.g. "Subscription Activated" for subscription_activated) can also be configured in the Userflow UI.

We recommend using event names consisting of a noun and a past-tense verb. Check out this great event naming guide by Segment.

You can explicitly set the data type for event attributes:

userflow.track('subscription_activated', {
  // This will be consumed as a string, even though its value
  // is a number here
  plan_name: {set: 12345678, data_type: 'string'}
})

userflow.startFlow(flowId)

Starts a flow for the currently signed-in user. The flow will display immediately.

Use this to programmatically start a flow when something happens in your app. You could, for example, implement a button called "Show onboarding tutorial again", which users can click after signing up to go through your tutorial again.

Parameter Type Description
flowId String, required ID of the flow to start. You can find a flow's ID in Userflow on the flow's "Link/Embed" tab. It's also the ID you see in the URL: /app/{company}/flows/{flowId}

Returns a Promise that resolves once the flow has been started.

Example:

userflow.startFlow('89eff72a-d0ae-4be6-b241-1ab04e3da7cc')

userflow.endAllFlows()

Ends all currently active flows, if any, for the user. The flows will be hidden immediately.

If the user does not have any active flows, nothing happens.

userflow.reset()

Makes Userflow forget about the currently active user and immediately hides any active flows.

Call this when users sign out of your app.

userflow.on(eventName, listener)

Registers an event listener to be called when the given event is triggered.

Parameter Type Description
eventName String, required Name of event to listen for. See list of supported events below.
listener Function, required Function to call when the event is triggered. Depending on the event, the function may receive arguments.

Supported events:

Event Arguments Description
flowvisibilitychange visible (boolean) Called with visible = true when a flow is shown (started) or with visible = fale when a flow is hidden (ended).

Example:

const listener = visible => {
  console.log(visible ? 'Flow is visible' : 'Flow was hidden')
}
userflow.on('flowvisibilitychange', listener)

// ...later, when no longer needed:
userflow.off('flowvisibilitychange', listener)

userflow.off(eventName, listener)

Removes an event listener previously registered with userflow.on.

Parameter Type Description
flowId String, required Name of event.
listener Function, required Function to that was added with userflow.on.

userflow.registerCustomInput(cssSelector, getValue)

Teaches Userflow.js to treat HTML elements in your app as custom text inputs.

This is useful if, for example, you use combo boxes and want Userflow to treat them like regular <input> elements. Instead of reading a value property (as we do with input elements), the text content of the custom input element is used instead. Or, you can supply a custom getValue function to customize how to read a string value from an element.

Note that you can call this function multiple times to support multiple kinds of custom inputs.

Parameter Type Description
cssSelector String, required Valid CSS selector that matches your custom input element.
getValue Function, optional If set, should be a function that takes an element and returns a string representing the custom input's current value. If not set, Userflow will default to using the text content of the whole element.

Example HTML markup:

<label>Fruit</label>
<div class="combo-box">
  <div class="combo-box-value">Banana</div>
  <div class="combo-box-trigger">..icon..</div>
</div>

Example Userflow.js configuration:

userflow.registerCustomInput('.combo-box-value')

It's now possible to make conditions in the Flow Builder using the value of inputs labeled with Fruit. It works just as if the markup had been like this:

<label>Fruit</label>
<div class="combo-box">
  <input type="text" value="Banana" />
  <div class="combo-box-trigger">..icon..</div>
</div>

Example of using the getValue function:

userflow.registerCustomInput('.combo-box', el => {
  const valueEl = el.querySelector('.combo-box-value')
  return (valueEl && valueEl.textContent) || ''
})

In this case, Userflow will return Banana as the value, and leave out the ..icon.. part.

userflow.setCustomNavigate(customNavigate)

By default, when performing Go to page actions, Userflow will cause full page loads using window.location.href = url.

Call this function to override this behavior.

This is useful for single page applications using in-app navigation through the window.history API.

Parameter Type Description
customNavigate Function or null, required A function taking a single string url parameter. Or null to turn off and use default behavior.

Example, where myRouter is a fictive router object:

userflow.setCustomNavigate(url => myRouter.push(url))

Example with React Router app:

// File: history.js
import {createBrowserHistory} from 'history'

export default createBrowserHistory()

// File: index.js
import {Router} from 'react-router-dom'
import history from './history'
import App from './App'

ReactDOM.render(
  <Router history={history}>
    <App />
  </Router>,
  document.body
)

// File: wherever-you-load-userflow.js
import history from './history'

// ...
userflow.setCustomNavigate(url => history.push(url))
// ...

userflow.setInferenceAttributeFilter(attributeName, filters)

Restricts HTML element attribute values from being used for element inference.

By default, Userflow.js may use all values of attributes configured with userflow.setInferenceAttributeNames. The only exception is that, by default, ids ending in numbers will be ignored. This is to support some dynamic IDs out-of-the-box.

Parameter Type Description
attributeName String, required The attribute name the filter should apply to. Example values: id, data-testid.
filters Function, RegExp instance, or an array of functions or RegExp instances, required When Userflow considers an attribute value, it'll be passed through all the given filters before we decide to use it. Filter functions are called with the attribute value and must return a truthy value to allow Userflow.js to use it. Regular expressions must match the attribute value to allow Userflow.js to use it. You can pass a single function, a single regular expression, or an array with a mix.

Example of ignoring all ids starting with auto-:

userflow.setInferenceAttributeFilters(
  'id',
  // Returns true if the id does not start with `auto-`
  id => !id.startsWith('auto-')
)

Example of using an array containing both a function and a regular expression:

userflow.setInferenceAttributeFilters('id', [
  // Ignore ids starting with `auto-`
  id => !id.startsWith('auto-'),
  // Only consider ids consisting of a-z and dashes
  /^[a-z-]+$/
])

userflow.setInferenceAttributeNames(attributeNames)

Tells Userflow.js which HTML element attributes can be used for element inference.

By default, Userflow.js may use the values of the following element attributes for inference:

  • data-for
  • data-id
  • data-testid
  • data-test-id
  • for
  • id
  • name
  • placeholder
  • role
Parameter Type Description
attributeNames Array of strings, required Hey

Example of overriding the list of attribute names to use:

userflow.setInferenceAttributeNames(['name', 'placeholder', 'data-testid'])

userflow.setInferenceClassNameFilter(filters)

Restricts CSS class names from being used for element inference.

By default, Userflow.js may use all class names.

Parameter Type Description
filters Function, RegExp instance, or an array of functions or RegExp instances, required When Userflow considers a class name, it'll be passed through all the given filters before we decide to use it. Filter functions are called with the class name and must return a truthy value to allow Userflow.js to use it. Regular expressions must match the class name to allow Userflow.js to use it. You can pass a single function, a single regular expression, or an array with a mix.

Example of ignoring dynamic class names starting with css-:

userflow.setInferenceClassNameFilter(
  // Returns true if the class name does not start with `css-`
  cls => !cls.startsWith('css-')
)

userflow.setScrollPadding(scrollPadding)

By default, when Userflow needs to scroll an element (e.g. the target of a tooltip) into view, we use the built-in Element.prototype.scrollIntoView method. This doesn't work well with sticky header/footers, since the element may be scrolled within the browser's viewport, but still be below the sticky header/footer.

To get around this, you can instruct Userflow to scroll just a little further in any direction in order to get the element inside the viewport and away from the sticky header/footer.

Note that this behavior will not work, and we'll fall back to plain Element.prototype.scrollIntoView, if the target element is nested within other scroll containers.

Parameter Type Description
scrollPadding Object or null Set to an object to use scroll padding. Set to null to turn off again.
scrollPadding.top Number, optional Padding from the top of the viewport (pixels)
scrollPadding.right Number, optional Padding from the right of the viewport (pixels)
scrollPadding.bottom Number, optional Padding from the bottom of the viewport (pixels)
scrollPadding.left Number, optional Padding from the left of the viewport (pixels)

Example, if you have a 50px tall sticky header:

userflow.setScrollPadding({top: 50})

Example, if you have a 50px tall sticky header and a 20px tall sticky footer:

userflow.setScrollPadding({top: 50, bottom: 20})

To turn off again:

userflow.setScrollPadding(null)

Got questions? We're here for you!

The best way to get help is to
We usually reply within 5 minutes
You can also send an email to support@getuserflow.com
We usually reply within a few hours