Custom JavaScript

The Product Tour-level JavaScript editor enables users to inject custom JavaScript code directly into their Product Tour demos. This tool provides flexibility for those with coding knowledge to enhance their demos beyond standard HTML and CSS customization.

Why Use JavaScript in Your Product Tours?

Adding custom JavaScript opens up new possibilities for advanced interactions and integrations, allowing users to:

  • Enable drag-and-drop functionality: Make demos interactive by incorporating drag-and-drop elements.
  • Customize autoscrolling behavior: Tailor scrolling dynamics for a smoother presentation flow.
  • Send data to analytics tools: Set up tracking and data flow to external analytics platforms.

In short, if you know how to code, the JavaScript editor gives you the freedom to customize your demo experience in ways that are often restricted on other platforms. It’s an added tool in your Product Tour creation toolkit, letting you build the exact experience you envision.

How to Access the JavaScript Editor

To access the JavaScript editor:

  1. Open your Product Tour demo in the editor.
  2. Navigate to Product Tour Settings > Custom Code.
  3. Toggle on CustomJS Editor to begin adding your JavaScript code

Screenshot 2024-11-13 at 10.43.16 AM.png

Note: While the JavaScript editor provides powerful capabilities, it requires technical expertise. If you’re new to JavaScript, consult with your technical team or explore resources on JavaScript fundamentals.


How Custom JS works

Custom JS adds a script tag to each canvas, giving you direct access to customize the behavior and functionality of your demo. It also exposes the reprise object from the RuntimeCanvas class to the global context on every screen. This enables you to structure your code to listen for on-screen events and execute demo actions seamlessly.

Available listeners

Custom JS provides several event listeners that you can hook into for enhanced interactivity. Here are the types of listeners available:

  • change_screen: Triggered when the screen changes. (does not fire on first screen load)
  • leave_screen: Triggered immediately before the screen changes.
  • mount: Triggered when the canvas is loaded on the first screen only.
  • flow_step: Triggered during every flow step. (includes first screen load)

Note: for the first leave_screen trigger, the context is empty due to limitations of our infrastructure. This only happens for the first screen, so if the context is empty then it is the first screen.

You can add listeners by using:

reprise.on(type, (context) => {
  // Your custom code here
});

Example:

reprise.on("change_screen", (context) => {
  console.log("Screen changed to: ", context.screen.title);
});

Example of a code setup so that the code fires once on all screens:

reprise.on("mount", (context) => {mainCustomJSFunction(context)}); // first screen
reprise.on("change_screen", (context) => {mainCustomJSFunction(context)}); // others

function mainCustomJSFunction(context) {
    // do something here
}

Understanding the listener context

The context parameter gives you useful information about the current state of the canvas. Here is a breakdown of what you can access:

type CustomJSContext = {
  screen: ScreenData | null;
  screen_id?: ContentNodeId | null;
  replay_id?: string;
  replay_title?: string;
  client_id?: string;
  environment?: "editor" | "preview" | "publish";
  flow_id?: ContentNodeId;
  last_screen_id?: ContentNodeId | null;
};

type ScreenData = {
  title: string;
  created_at: string;
  properties: Record<string, unknown="unknown">;
  screenshot_small: string;
  display_width?: string;
  page_info?: ScreenPageInfo;
  screen_type?: ScreenType;
};
  • screen: Details about the current screen (e.g., title, creation date, properties).
  • screen_id: The ID of the current screen.
  • replay_id and replay_title: Identifiers for the demo. These field names predate the Product Tours rename and are unchanged in the API.
  • client_id: The client ID if available.
  • environment: Indicates whether the canvas is in editor, preview, or publish mode.
  • flow_id: The flow ID of the new screen.
  • last_screen_id: The screen ID of the previous screen.

Screen data:

  • title: The screen title.
  • created_at: Timestamp of when the screen was created.
  • properties: A record of custom properties for that screen.
  • screenshot_small: URL of a small screenshot preview.

Executing actions with reprise.execute_action()

Custom JS also allows you to execute actions that control the flow of your demo. You can use reprise.execute_action(action: FlowAction) to trigger predefined flow actions.

Available actions

  • flow_next: Moves to the next flow step.
  • flow_prev: Moves to the previous flow step.
  • flow_next_screen: Moves to the next screen.
  • flow_prev_screen: Moves to the previous screen.
  • goto_screen: Jumps to a specific screen by providing the screen_id.
// Example for navigating to a specific screen
reprise.execute_action({
  type: "goto_screen",
  screen_id: "scnr-1234"
});

// Example for moving to the next screen
reprise.execute_action({
  type: "flow_next_screen"
});

// Example for moving to the next flow step
reprise.execute_action({
  type: "flow_next"
});

Sending messages with reprise.post_message()

In addition to executing actions, you can send messages using reprise.post_message(message: any). This method sends a message up the iframe to the parent, so it can be listened for when the demo is embedded in an iframe.

reprise.post_message({
  event: "custom_event",
  data: {
    key: "value"
  }
});

This sends a message to the top-level window, allowing you to pass information between your custom JS and other scripts or systems.

Controlling guide visibility with reprise.guides

You can give viewers a control that shows or hides the demo’s guides during playback. reprise.guides exposes three methods:

  • hide(): Hides the authored guides.
  • show(): Restores them.
  • toggle(): Flips between the two.

Bind your own control with a capture-phase listener, so the click reaches your code before the demo handles it:

document.addEventListener("click", function (e) {
  if (e.target.closest("#toggle-guides")) {
    e.stopImmediatePropagation();
    window.reprise?.guides?.toggle();
  }
}, true);

Hiding guides doesn’t change which screen the viewer is on, and click-to-advance keeps working while guides are hidden, so viewers can still move through the demo.


Was this article helpful?
0 out of 0 found this helpful
Have more questions?
Submit a request
Share it, if you like it.