The flexibility provided by the endpoint allows developers to quickly update the application's appearance
and functionality without needing to modify the underlying code.
Layout types
Main Layout
Rendering
Main layout can be rendered in two different ways, and is defined via rendering_type field under main layout configuration.
Window titling
The default title of the browser window must be defined in main layout configuration.
However, it can be overwritten by optionally configured title of an individual app configurations.
Analytics
The analytics settings can be defined in the flow configuration along with layout configuration.
Analytics configuration resides under analytics key in the flow configuration.
List of partners which analytics can be enabled for a site:
GA Tracking
{
"analytics": {
"google_analytics_tracking_parameters": ["utm_campaign", "guid"]
}
}
When the user navigates to ``, Site will
send a staircase_page_view event to Google Analytics with the following parameters:
{
"utm_campaign": "email",
"guid": "98903487222"
}
Site Advertisement
{
"analytics": {
"advertiser_correlation_key": "utm_source"
}
}
Defines the query parameter to look up advertiser's information at. When user visit ``,
Site will perform Persist Advertiser Data
with utm_source's value as an advertiser_id. The data will be collected from query parameters and passed on for the further translation.
Consent
Cookie consent is automatically enabled for any site that has analytics enabled.
It is fully managed by the Site product and does not require any additional configuration.
However, it can be customized with the consent configuration under cookie_consent key.
Cookie Consent Configuration Example
{
...
"analytics": {
"google_analytics_tag": "G-9TJJ8RPE4H"
},
"cookie_consent": {
"popup": {
"title": "Got time for cookies?",
"button_ok": "Sure"
}
}
}
Review the schema of cookie_consent for more customization options.
Error Pages
Error page content can include full HTML markup, including CSS and JavaScript.
Avoid bloating the page with unnecessary resources, as it will affect the page load time.
Note: the Site product restricts access to visitors with IP addresses from the United States only. Traffic from IP addresses outside the U.S. is not permitted.
Example
{
...
"layout_configuration": { ... },
"analytics": { ... },
"error_pages": {
"forbidden": {
"page_content": "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Access Restricted</title><style>body{font-family:Arial,sans-serif;background-color:#f4f4f4;text-align:center;padding:50px}.container{background-color:#fff;margin:auto;width:60%;padding:20px;box-shadow:0 4px 8px rgba(0,0,0,.1)}h1{color:#333}p{color:#666}a{color:#007bff;text-decoration:none}a:hover{text-decoration:underline}</style></head><body><div class=\"container\"><h1>Access Restricted</h1><p>Sorry, this content is not available in your region.</p><p>Your IP address has been identified as not originating from the United States. For compliance reasons, we cannot grant access to users outside this region.</p><p>If you believe you have received this message in error, please contact support atsupport@example.com.</p></div></body></html>"
}
}
}
(IMPORTANT) Custom Domains
When you change error_pages in the Site configuration, remember to sync the Site deployments.
- Register Configuration with
error_pages configuration.
- Deploy Configuration to the distribution network.
- Synchronize custom Site.
Open Graph Protocol
Site provides a way to define OGP tags inside the Site configuration.
We follow for the most part with slight modifications. Namely:
og:type can only be set to website as is required.
og:description is a required parameter.
og:locale can only be set to en_US and is required
og:site_name is required for ANY website.
In the original OGP these fields are optional. For a configuration example navigate to a request payload example named "Open Graph Tags".
Best Practices for OGP Images
- Aspect Ratio: The most widely recommended aspect ratio for OG images is 1.91:1. This ratio is optimal for platforms like Facebook, LinkedIn, and Twitter.
- Dimensions:
- Minimum Size: At minimum, your image should be 600 x 315 pixels (width x height). However, this is quite small and might not look great on high-resolution displays.
- Optimal Size: A more commonly recommended size is 1200 x 630 pixels. This size tends to work well on most social networks and provides a good balance between file size and image quality.
- Maximum Size: For some platforms like Facebook, the maximum image size can be up to 4096 x 4096 pixels, but such large images are rarely necessary and can increase page load times.
- File Size: Keep an eye on the image file size. It's generally recommended to keep it under 300 KB to ensure fast loading times, as large images can slow down your page's performance.
- File Type: Use JPEG for photographic images to save bandwidth, or PNG for images with text, logos, or simple graphics where clarity is important.
Path Mappings
Path mappings can be defined in the flow configuration along with layout configuration.
Path mappings allow you to define a set of rules that will be applied to the behavior of the Site when the certain URL path is provided.
If the URL path matches the rule, the user will be redirected to the specified URL path.
Request URL attributes such as query parameters will be preserved, but are not allowed to be defined in source path.
Note: Requests without Host header provided will not be eligible for a proper redirect response. As those requests will be considered malicious.
Path mappings configuration resides under path_mapping key in the flow configuration.
Examples
The redirect response example (the actual response may vary):
HTTP/2 302
server: CloudFront
date: Wed, 19 Jul 2023 04:21:00 GMT
content-length: 75
cache-control: public, max-age=86400, immutable
location:
* Connection #0 to host staircase.co left intact
<!DOCTYPE html><html><body><p>You are being redirected...</p></body></html>
Take a closer look at Cache-Control.
The maximum caching age value is set by the server and cannot be changed.
The server will direct the viewer to cache the response for 24 hours.
Validation rules
For the URL path:
- Must not contain leading or trailing slashes. E.g.,
/about-us/ must be corrected to about-us.
- Must be already URL encoded. E.g.,
about us must be corrected to about%20us.
- Must not contain anything other than alphanumeric characters, forward slash, period, and dash. It should match
^[a-z0-9]+([./-][a-z0-9]+)*$ regular expression.
- Must not contain query parameters. E.g.,
about-us?utm_source=google must be corrected to about-us.
For the complete URL:
- Must contain the
URL schema. E.g., example.staircase.co must be corrected to ``.
- Must not contain query parameters. E.g.,
must be corrected to.
- Must not contain fragment identifiers. E.g.,
must be corrected to.
Use cases
Internal redirects
Redirect to a different URL on the same domain name.
Problem statement
We need to redirect all requests from the old pricing.html page to the new pricing page located at a different URL path, ensuring this redirection is permanent.
Configuration
{
...
"layout_configuration": { ... },
"analytics": { ... },
"path_mappings": [
{
"from_path": "pricing.html",
"to_path": "pricing"
},
{
"from_path": "legal-terms.html",
"to_path": "legal"
}
]
}
We have added a new path mapping rule to the flow configuration, which will redirect all requests from pricing.html to pricing path.
External redirects
Redirect to a different URL on a different domain name.
Problem statement
We would like to move part of the existing application, to a completely new site configuration, under the different domain name.
It's currently hosted on and we would like to move it to.
Configuration
{
...
"layout_configuration": { ... },
"analytics": { ... },
"path_mappings": [
{
"from_path": "exchange",
"to_path": ""
}
]
}
We have added a new path mapping rule to the flow configuration, which will redirect all requests from exchange to `` path.
Notes
Custom Domains
When you change path_mapping in the Site configuration, remember to sync the Site deployments.
- Register Configuration with
path_mappings configuration.
- Deploy Configuration to the distribution network.
- Synchronize custom Site.
Custom Authentication
Site provides a way to manage the authentication of the user using custom console app.
Authentication requirement can be defined in the Site configuration as following using authentication_action.
Communication
Query Parameters
The following parameters are loaded
Events
The following event is expected to be emitted by the custom console app to the Site.
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"authentication_completed": {
"type": "boolean",
"description": "Describes whether the authentication flow has been completed.",
"enum": [true]
},
"next_console_app_configuration_id": {
"type": "string",
"description": "Describes the console app configuration. Tells the Site to load an app marked by this field."
},
"auth": {
"type": "object",
"description": "What authentication context screen to load.",
"properties": {
"access_token": {"type": "string"},
"id_token": {"type": "string"},
"refresh_token": {"type": "string"}
}
}
},
"required": [
"listener",
"next_console_app_configuration_id",
"auth",
"authentication_completed"
]
}
Cookies
When the user is redirected back to site after Sign In by SSO or Sign Up authentication flow,
site instructs browser to store a cookie named accessToken with the value of the access token provided in the URL hash.
e.g., when visiting site with ``,
the Site will instruct user's browser engine to store a cookie named accessToken with a value 1234.
Additionally, cookie will have the following attributes:
Domain – the domain name will be bound to the environment FQDN currently serving the backend APIs. e.g., production.staircaseapi.com
Path – the path will be bound to the root path /.
Secure – the cookie will be marked as secure to be transmitted to HTTPS origins exclusively.
HttpOnly – the cookie will not be accessible via JavaScript. It can only by the CDN request interceptor (CloudFront functions), or an API accessible under the same domain name.
SameSite – the value will be set to None to avoid improper cookie setting given the iframe context.
Expires – the value will be set to expire in 6 hours from when the request has been made.
Currently, the __sc.acact cookie (represent the access token) set by site is considered as a third-party cookie, so you must apply
caution when using API calls for authentication.
Example
{
"authentication": {
"enabled": true,
"show_authentication_on_load": false,
"console_app_configuration": { ... }
}
"layout_configuration": {
"main": {
...
"console_app_configurations": [
{
"console_app_configuration_id": "6374c7f8-13fa-454a-8587-bd2972434bbb",
"temporary__console_app_url": "/6374c7f8-13fa-454a-8587-bd2972434bbb-copy34/",
"authentication_action": "signin",
"url_suffix": "/conversations"
}
]
}
}
}
Before accessing /conversations the user, if not already authenticated,
will be redirected to the /signin path and the custom console app will be loaded for authentication.
Advanced
State Exchange
Custom authentication apps should utilize authentication_state to provide smooth user experience.
Upon loading in an iframe, the app receives a query parameter: authentication_state,
a short string of random characters. It's crucial to retain the authentication state,
particularly when the authentication flow is interrupted by external redirections.
Common scenarios include Sign Up processes, and authentications via SSO providers like Google, Amazon, or Facebook.
The app should provider users with a link for redirection whenever necessary based on the authentication scenario.
The Sign Up process is notable as it requires redirection from an email link for account activation.
The site expects the "return" of the state key in the URL hash.
Example
<!-- The app is initially loaded within an iframe, with the authentication_state parameter -->
<iframe src="" width="100%" height="500"></iframe>
<!-- A redirection occurs during the authentication flow for Google login -->
Login using Google
In this example:
- The app is loaded in an iframe and receives the authentication_state parameter.
- During the authentication flow, a redirection for Google login is required. The user is provided a link to login via Google.
- Upon clicking the link, the user completes the Google login process.
- The user is redirected back to test.staircase.co with the URL hash
#state=p1d048R.
- The site, having associated this state with the data in local storage, uses it to load the most recently used console app.
This scenario emphasizes the importance of managing the authentication_state parameter effectively
to maintain a smooth user experience in cases involving external redirections like authentication via SSO.
Soft Authentication
Everything described above is considered as a soft authentication. It does force authentication on the user,
but it does not validate the user's identity. The user can easily bypass the authentication.
Soft authentication is useful for when it's not required to validate the user's identity.
Authorization
Forced validation cannot be achieved via the Site configuration. There will always be a way to bypass the authentication,
instead apps must apply the Cookie validation logic to ensure the user is authenticated. The cookie validation can simply
be achieved by validating the JWT token stored in the __sc.acact cookie, which represent access token from Access.
If the app has an API it communicates with to retrieve the data that should not be generally available,
the API must implement the access token validation logic to ensure the user is authenticated.
The Site product enables such functionality by setting HttpOnly cookies accessible to every API that the console app consumes.
Console App and Site Communications
The Site allows two-way communication between the Site and the Apps using
postMessage method.
Console App to Site
Embedded Apps can communicate with the Site using window.parent.postMessage(payloadObject, "*");.
postMessage was introduced to eliminate API calls from the Apps to Site endpoints.
A unit of communication is a "message", which in itself is a JavaScript object with a required property listener.
The value for the listener must correspond to the Site product identifier.
Fact: Site product identifier is e9cc145f-9d03-422e-ba71-1852885998e6
The list of events accepted by Site is described below.
Relocate the User
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"relocation_action": {
"type": "string",
"description": "Describes the action to be taken by the Site.",
"enum": [
"REPLACE_CURRENT_URL",
"OPEN_NEW_TAB",
"OPEN_DEFAULT"
]
},
"relocation_url": {
"type": "string",
"description": "The URL to be loaded by the Site."
}
},
"required": [
"listener",
"relocation_action",
"relocation_url"
]
}
Toggle Popup
Note: layout_configuration should contain popup definition for the toggle to work.
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"style": {
"type": "object",
"description": "Styling attributes. Standard CSS attributes.",
"additionalProperties": {
"type": "string"
}
},
"showPopup": {
"type": "boolean",
"description": "Marks the popup state. Use `true` – to show, `false` – to hide popup."
}
},
"required": [
"listener",
"style",
"showPopup"
]
}
Load Authentication Page
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"auth_screen": {
"type": "string",
"description": "What authentication context screen to load.",
"enum": [
"signin",
"signup",
"forgot-password",
"forgot-password-update"
]
}
},
"required": [
"listener",
"auth_screen"
]
}
The feature can also be accessed via the configuration via authentication_action field under layout_configuration.main.console_app_configurations[*].
Logout the User
Note: You can define logout_url under layout_configuration.authentication to redirect the user to the desired URL after the authentication reset.
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"logout": {
"type": "boolean",
"description": "Whether to logout the user. Can only be `true`.",
"enum": [
true
]
}
},
"required": [
"listener",
"logout"
]
}
Load Console App
Note: console_app_configuration_id should be present among console app configurations registered for the active flow configuration, and not just any console app configuration identifier.
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"console_app_configuration_id": {
"type": "string",
"description": "Describes the console app configuration. Tells the Site to load an app marked by this field."
}
},
"required": [
"listener",
"console_app_configuration_id"
]
}
Change Browser Tab URL
Note: url_suffix property should be a path, not a full URL.
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"url_suffix": {
"type": "string",
"description": "URL to be set in user's browser tab."
}
},
"required": [
"listener",
"url_suffix"
]
}
Warning: This feature is exclusive to site configurations with a single console app configuration.
Send Custom Tracking Event
Sends a custom tracking event to the analytics provider. Right now only Google Tag Manager and Facebook Pixel are supported.
It is recommended to use Google Tag Manager and manage data destinations from there, including Facebook
Note: This will work only if the analytics configuration is present in the flow configuration.
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"externalFeedbackProvider": {
"type": "string",
"enum": ["pixel", "gtm"]
},
"type": {
"type": "string",
"example": "trackCustom"
},
"action": {
"type": "string"
},
"data": {
"type": "object"
}
},
"required": [
"listener",
"externalFeedbackProvider",
"action",
"data"
]
}
Restyle Console App
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"style": {
"type": "object",
"additionalProperties": true,
"description": "Apply different than original styles dynamically using a set of key-value pairs where the keys are CSS properties"
},
"target": {
"type": "string",
"description": "A site component placeholder, which requires a change in styling.",
"enum": ["header", "left_sidebar", "right_sidebar", "footer", "hero", "main"]
}
},
"required": [
"listener",
"style",
"target"
]
}
Dynamically Resizing Main Layout
In order to keep the footer on the bottom of the page, the main layout height should be adjusted dynamically.
To its dynamic height.
The following example demonstrates how to use ResizeObserver
to monitor document height changes, and send a message to the Site to adjust the height of the main layout.
const emitResizeSelfDimensions = ({height}) => {
const resizeMeEvent = {
listener: "e9cc145f-9d03-422e-ba71-1852885998e6",
style: {height},
target: "main"
};
window.parent.postMessage(resizeMeEvent, '*');
}
const resizeObserver = new ResizeObserver(
entries => {
for (let entry of entries) {
const newHeight = entry.contentRect.height;
emitResizeSelfDimensions({height: newHeight});
}
}
)
resizeObserver.observe(document.body)
Important: Site automatically applies margin-top and z-index for the header, so it's kept on top while scrolling.
Pass on the Data
When the payload property is passed together with direction or console_app_configuration_id fields,
Site converts that value into the URL-encoded string and passes it to the console app configuration as a query parameter.
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"console_app_configuration_id": {
"type": "string",
"description": "Describes the console app configuration. Tells the Site to load an app marked by this field."
},
"direction": {
"type": "string",
"description": "Describes the direction of the flow. Tells the Site what to load next.",
"enum": ["backward", "forward"]
},
"payload": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"required": [
"listener"
]
}
Refresh access and ID tokens
Site allows refreshing the access and ID tokens by sending a message to the Site if refresh token is persisted.
Note, that currently refresh token is generated by Access only for email-password flow and is not provided for SSO.
If your application uses custom auth app, that app have to send refresh token to the Site
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"eventType": {
"type": "string",
"description": "Event type.",
"enum": [
"refreshAccessToken"
]
}
},
"required": [
"listener",
"eventType"
]
}
Data-driven Site Flow
If none of console_app_configuration_id or direction were provided, the Site will treat the flow as
conditionally driven. It will go through every console app configuration until it matches provided data
to a specified condition.
Site to Console App
Embedded Apps can listen to the Site event using window.addEventListener.
In the case of Site to Console App communication the value for the listener corresponds to the console application configuration receiving the message.
Every message sent by the Site to the Console App has a fixed structure.
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Console application configuration identifier."
},
"eventType": {
"type": "string",
"description": "Describes the event type that has occurred.",
"enum": [
"main_app_change"
]
},
"eventPayload": {
"type": "object",
"description": "Event payload. Varies depending on the event type."
}
},
"required": [
"listener",
"eventType"
]
}
The Main Console App Has Changed
The current main application configuration has changed to a different one.
Warning: When a non-main console application configuration with inherit_main_url: true gets initialized, it is not guaranteed that the event will be emitted to the console application through the Site. Instead, the console application can rely on main_url_path passed as a query parameter when loading the console application. Same goes for is_authenticated
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Console application configuration identifier."
},
"eventType": {
"type": "string",
"description": "Describes the event type that has occurred.",
"enum": ["main_app_change"]
},
"eventPayload": {
"type": "object",
"description": "Event payload. Can contain additional properties depending on the `change_reload_url_params` definition in the console app configuration.",
"required": ["console_app_configuration_id", "is_authenticated"],
"properties": {
"main_url_path": {
"type": "string",
"description": "URL path of the main console app configuration. Provided if `inherit_url_path` is enabled."
},
"console_app_configuration_id": {
"type": "string",
"description": "Console app configuration identifier of the switched app."
},
"is_authenticated": {
"type": "boolean",
"description": "Correlation flag. Indicates whether the user is authenticated or not."
}
}
}
},
"required": [
"listener",
"eventType",
"eventPayload"
]
}
Warning: Do not use is_authenticated flag for authorization purposes. It's only meant to be used to correlate the state between site and console applications.
Ratio Based Application Loading
Main console application configuration can be configured to load different applications based on the ratio.
The main use-case for the ratio based application loading is A/B testing
on the level of the application configuration.
When rendering such application, the Site will randomly select one of the application configurations
(defined in ratio_based_console_app_configurations under the main application configuration)
based on the ratio defined in the configuration. Site uses weighted random selection to determine which application
configuration to load.
Note: Defining the ratio based applications still requires defining the console_app_configuration_id and temporary__console_app_url properties.
Validation Rules
The following rules are designed to ensure the ratio based application loading is configured correctly:
ratio_based_console_app_configurations must contain the original application configuration in the list of the alternative application configurations.
- Each application configuration under
ratio_based_console_app_configurations must contain the ratio.
- The ratio for each application configuration must be a positive number greater than
0.0 and less than 1.0.
- The sum of all ratios must be equal to
1.0.
Navigate to endpoint request payload Flow with A/B Applications example to see the example
of the ratio based application site configuration.
Conditional flows
Conditional flows are a particular way of Site flows where the logic of which App should be displayed depends on the data passed in postMessage. First, the Site configuration should contain condition property set on all Apps except the first one. An example:
...
"console_app_configurations":
{
"console_app_configuration_id": "6374c7f8-13fa-454a-8587-bd2972434bbb",
"temporary__console_app_url": "",
"url_suffix": "/welcome"
},
{
"console_app_configuration_id": "6374c7f8-13fa-454a-8587-bd2972434ccc",
"temporary__console_app_url": "",
"url_suffix": "/option-one",
"condition": {
"path": "optionSelected",
"operation": "equal",
"value": "1"
}
},
{
"console_app_configuration_id": "6374c7f8-13fa-454a-8587-bd2972434ddd",
"temporary__console_app_url": "",
"url_suffix": "/option-two",
"condition": {
"path": "optionSelected",
"operation": "equal",
"value": "2"
}
}
}
...
When the Site is opened, the /welcome page will be displayed. Let's assume that /welcome page contains some form and, depending on the value selected by the User, one of the other two Apps should be displayed. After the User submits the value on /welcome App, the App invokes window.parent.postMessage({"listener": "e9cc145f-9d03-422e-ba71-1852885998e6", "payload": {"optionSelected": submitedValue}}, "*"); with submitedValue. The Site receives the payload, checks for the conditions and if the submitedValue is equal to 1 displays /option-one App or /option-two if the submitedValue is equal to 2. The Site passes to the App optionSelected as a query parameter, for example, if submitedValue was equal to 2 it will load the App like ``.
Note:
- if the condition passed in
postMessage payload does not match any of the conditions in the Site configuration, the User will remain on the same App
- if multiple Apps conditions match the passed payload, the first one will be displayed
- the Site does not do casting when comparing conditions and treats all values as strings
Using complex conditions
The Site allows conditions to be complex using and and or operations. Example of such Site configuration:
...
{
"console_app_configuration_id": "6374c7f8-13fa-454a-8587-bd2972434ddd",
"temporary__console_app_url": "",
"url_suffix": "/option-two",
"condition": {
"and": [
{
"path": "optionSelected",
"operation": "equal",
"value": "1"
},
{
"path": "userAge",
"operation": "greatherThan",
"value": "21"
}
}
}
}
...
In this case, conditions are matched if only both optionSelected equals 1 and userAge is greater than 21.
Similarly, using or operator instead of and will be matched if one of the conditions is meet.
User State & Workflows
Warning: Workflows can only be used for flows with authentication enabled. If the site visitor is not authenticated and tries entering the workflow, they will be directed to the authentication page.
Workflows help in consistently saving user state data between various console app settings.
A workflow is essentially a blueprint detailing the user's journey.
You have the option to set up to 10 distinct workflows for each site configuration.
It's crucial that every workflow is marked with a unique identifier and its corresponding path.
When a user wraps up a state (in this case, a console app), the app then signals the completion to the Site.
Subsequently, the Site initiates the loading of the forthcoming state.
Should a user return to the site, the Site will automatically load their most recent state, presenting it directly to the user.
Defining a Workflow
The framework to define a workflow resemble the [States Language seen in AWS Step Functions.
However, it's a more condensed structure.
Key distinctions include:
- The
Type property of a State can solely be App.
- The
Resource pertains to a console app configuration ID.
- Every
States should possess a distinctive Resource property.
Events for Workflows
State Done
Tells site to load the Next app in the workflow.
If the current state is terminal (End: true) nothing is changed.
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"state_done": {
"type": "boolean",
"description": "Represents the state completion by the user. Can only be `true`.",
"enum": [
true
]
}
},
"required": [
"listener",
"state_done"
]
}
Switch Workflow
Tells site to load to switch from one workflow to a different one.
If the workflow specified does not exist – nothing will change.
{
"$schema": "",
"type": "object",
"properties": {
"listener": {
"type": "string",
"description": "Site product identifier.",
"enum": [
"e9cc145f-9d03-422e-ba71-1852885998e6"
]
},
"workflow_id": {
"type": "string",
"description": "Represents the workflow identifier."
}
},
"required": [
"listener",
"workflow_id"
]
}
URL Paths & Workflow
Each workflow is tied to a specific path.
When a user accesses a URL that matches this path, they are directed into that particular workflow.
Note that a workflow will absorb all url_suffixes defined for states in Resource.
This implies that if a url_suffix is set, it must be distinctly different from other url_suffix definitions.
See an example for a workflow definition in an example named "Stateful".
Important: Modify identifiers for both site and console app configurations before using examples below.
Custom domain for backend and console apps
The Site product allows you to use a custom domain for the backend and console apps.
To use a custom domain you need to add backend.domain_name to your site configuration.
Site will use this domain to load the console apps and to make requests to the backend.
Example:
{
"backend": {
"domain_name": "api.example.com"
}
}