Extending and querying your flow at runtime via custom JavaScript can sometimes be challenging due to the underlying structure of the flow document not being something that you control, but being assembled by a different platform that can hold changes over time.
In order to bring in stability and some ease of use for your custom JavaScript, you can make use of our FlowSDK (Software Development Kit), which allows you controlled access to different mechanisms and data in your flow at runtime.
When you visit a flow a lot of things happen under the hood, be it initialization and rendering of your blocks, registering and dispatching of events, running 3rd party integrations etc.
The FlowSDK hooks into all these things and provides you with certain functions to either read, write or execute data and functions in a way the system around it expects it.
đ Learn more about custom JavaScript here.
Heyflow Events
The FlowSDK is part of our Heyflow Event system and accessible there via the detail property of the event object. Notice that we use a simple versioning system around the FlowSDK in order to avoid breaking changes over time:
â
window.addEventListener(âheyflow-initâ, (event) => {
const flowSDK = event.detail.flowSDK.v1;
});
The FlowSDK can be accessed in every Heyflow event.
FlowSDK functions
additionalResponseData
You can use this object to add, remove or manipulate additional response data that would be sent when the user submits your flow. A common use case is to add further hidden fields to the response, like UTM parameters and such.
flowSDK.additionalResponseData.set(âmy-valueâ, âhelloâ);
flowSDK.additionalResponseData.set(âmy-advanced-valueâ, { value: 3 });
flowSDK.additionalResponseData.set(âmy-more-advanced-valueâ, { value: false, label: âtestâ });
flowSDK.additionalResponseData.set(âmy-valueâ, âhello-2â);
flowSDK.additionalResponseData.get(âmy-valueâ); // âhello-2â
flowSDK.additionalResponseData.remove(âmy-valueâ);
flowSDK.additionalResponseData.getAll(); // { âmy-advanced-valueâ: { value: 3}, âmy-more-advanced-valueâ: { value: false, label: âtestâ } }
getCurrentScreenID and getCurrentScreenName
Use these functions to receive information about the screen the user is currently viewing.
flowSDK.getCurrentScreenID(); // âscreen-f0453c16â
flowSDK.getCurrentScreenName(); // âstartâ
getFlowRoot
Depending on how you integrated your flow it can be hard to sometimes find the root of the flow, which could be used for different things like adding event listeners, querying the DOM etc. This function helps you with that:
lowSDK.getFlowRoot(); // document in a standalone flow for example
flowSDK.getFlowRoot(); // ShadowRoot if you embedded your flow via our embed widget, which uses the shadowDOM via custom web components
flowSDK.getFlowRoot(); // document in a standalone flow for example
requestNavigation
You can also navigate around your flow programmatically, by requesting a navigation:
flowSDK.navigation.goNext(); // Navigates to the next screen
flowSDK.navigation.goBack(); // Navigates to the previous screen
flowSDK.navigation.goToScreen(âscreen-31d412aâ); // Navigates to the given screenID
â Please note that forward navigation causes a screen to validate and is actually prevented when trying to leave an invalid screen (which is why you can only ârequestâ a navigation, but not directly do so).
validateScreen
You can validate a screen by calling this function. Screen validation is asynchronous, so keep that in mind. You get a boolean result which indicates the validity of the screen.
flowSDK.validateScreenByID(âscreen-1ab442aâ).then(console.log); // { success: boolean }
flowSDK.validateScreenByName(âstartâ).then(console.log); // { success: boolean }
Block functions
Retrieving blocks
To retrieve blocks, you can leverage multiple functions from the FlowSDK. See more on how to interact with them in the next section.
flowSDK.getBlocks(); // Just gives you all blocks of your flow
flowSDK.getBlockByID(âmc-4124122â); // Gives you the one block you are looking for
flowSDK.getBlocksByScreenID(âscreen-f0453c16â); // Gives you all the blocks of the screen you are looking for
flowSDK.getBlocksByScreenName(âstartâ); // Gives you all the blocks of the screen you are looking for
getValue and setValue
Almost all our blocks containing user data are implementing these functions, you can use to manipulate the current state of a block easily. Blocks that donât support these functions in v1 are:
Address & Map
Calendly
Signature
Stripe Checkout
Upload
The âPhone Numberâ block only supports setting a phone number, not changing the country in v1.
const block = flowSDK.getBlockByID(âinput-4124122â); // A input block
const value = block.getValue(); // âhelloâ
block.setValue(`${value} my-name`);
block.getValue(); // âhello my-nameâ
Sometimes a block uses a different format other than a simple string to work with values. See the list here:
Checkbox:
boolean
Multiple Choice:
string[]
a list of optionIDs, due to the multi variant of this blockSelect:
string|null
the optionID of the option to select
validate
This function triggers a validation of a block. Imagine a scenario where you expect the user to put in some data via your custom JS and now you want to see if the flow/screen is still actual valid:
block.validate().then(console.log); // { success: boolean }
â Itâs important to understand that depending on the block a validation could trigger a module usage like network validation in the phone block for example. This also the reason, the method is actual asynchronous.
reset
This function resets the block to the initial state, just like emptying a form:
block.reset();
Visibility Management
Programmatically control the visibility of a block.
show() - Show a block
hide() - Hide a block
get() - Get visibility state:
true
(shown),false
(hidden), orundefined
(default state).
clear() - Reset visibility state back to default
const block = flowSDK.getBlockByID('input-4124122');
block.visibility.show();
block.visibility.hide();
const state = block.visibility.get(); // true | false | undefined
block.visibility.clear();
Custom methods
For some blocks, we provided custom methods that might come in handy.
Checkbox
We allow to programmatically manipulate the label of the checkbox. Notice that you can HTML here:
block.setLabel(â<p>My own label</p>â);
Select
We allow getting and setting the options of a Select block programmatically:
const options = block.getOptions();
// [
// {
// id: âoption-124191â,
// label: âMy labelâ,
// systemLabel: âmy-optionâ
// }
// ]
block.setOptions([...options, {
id: âoption-124191â,
label: âMy labelâ
});
Input
We allow getting and setting the auto complete options of the block:
const autoCompleteOptions = block.getAutoCompleteOptions(); // [ âoption1â ]
block.setAutoCompleteOptions([âoption2â]);