Skip to main content

Embedding Marketplace

The video above demonstrates the process of embedding Prismatic in your application, starting from a blank React application.

Embed the integration marketplace

You can embed the Integration Marketplace into your application with minimal code, providing your customers with a native integration deployment experience. This article details the implementation of Prismatic's integration marketplace within your application.

For information on installing the embedded SDK and authenticating customer users, see Installing Embedded SDK

Once a user has been authenticated, you can render the integration marketplace using the prismatic.showMarketplace() function. The showMarketplace() function accepts three optional parameters:

  • usePopover: Determines whether the marketplace should render as a popover.
    By default, the screen is injected as an iframe into an existing DOM element.
  • selector: Specifies the DOM element to inject the iframe into when usePopover is false.
  • theme: Overrides custom theming default behavior, accepting either "LIGHT" or "DARK" mode.

iframe injection method

When showPopover is set to false, an iframe HTML element is injected into the element specified by the selector parameter. The iframe contains the integration marketplace.

For example, if you have a section of your application that reads:

<div id="integration-marketplace-placeholder" style="height:100%">
Loading...
</div>

You can inject the integration marketplace iframe into that div, replacing the "Loading..." text, by invoking:

prismatic.showMarketplace({
selector: `#integration-marketplace-placeholder`,
usePopover: false,
});

The result is that the integration marketplace appears as a portion of the rest of your application:

Prismatic integration marketplace embedded in your app

Note: At this point, the marketplace has not been themed to match your application. To implement custom branding, see Theming Embedded Marketplace.

For an example of the iframe injection method, see GitHub.

Popover method

If you set usePopover to true, the integration marketplace will render in a popover:

prismatic.showMarketplace({
usePopover: true,
});
Enable popover for Prismatic embedded marketplace

Filtering integrations

You can filter the displayed integrations by applying filters to your showMarketplace() invocation.

Simple integration filters

You can filter integrations by a single category or label (or both). If both filters are applied, integrations must match both category and label to be displayed.

For example, to display only integrations with the category "ERP" and the label "enterprise" in an embedded marketplace, use:

Filter by category and label
prismatic.showMarketplace({
selector: `#my-div-id`,
usePopover: false,
filters: {
marketplace: {
category: "ERP",
label: "enterprise",
},
},
});

Advanced integration filters

You can implement more sophisticated filtering logic using a filterQuery. You can query integrations based on their name, labels, or category. The following operators are available:

  • TermOperator.equal: Checks if the first term equals the second term, applicable to name and category. Example: To display only the "Dropbox" integration:

    prismatic.showMarketplace({
    filters: {
    marketplace: {
    filterQuery: [TermOperator.equal, "name", "Dropbox"],
    },
    },
    });
  • TermOperator.notEqual: Checks if the first term does not equal the second term, applicable to name and category. Example: To display all integrations except those with the category "ERP":

    prismatic.showMarketplace({
    filters: {
    marketplace: {
    filterQuery: [TermOperator.notEqual, "category", "ERP"],
    },
    },
    });
  • TermOperator.in: Checks if the integration's labels include a specific label. Example: To display integrations with a "paid" label:

    prismatic.showMarketplace({
    filters: {
    marketplace: {
    filterQuery: [TermOperator.in, "labels", "paid"],
    },
    },
    });
  • TermOperator.notIn: Displays integrations that do not have specified labels.

  • TermOperator.startsWith: Checks if a name or category begins with a specific string. Example: To find all integrations starting with "Algolia":

    prismatic.showMarketplace({
    filters: {
    marketplace: {
    filterQuery: [TermOperator.startsWith, "name", "Algolia"],
    },
    },
    });

    This will match integrations with names like Algolia - Dropbox or Algolia - SFTP.

  • TermOperator.doesNotStartWith: Returns integrations with names or categories that do not start with a specific string.

  • TermOperator.endsWith: Returns integrations with names or categories that end with a specific string.

  • TermOperator.doesNotEndWith: Returns integrations with names or categories that do not end with a specific string.

You can combine multiple conditions using and and or logic. For example, to display all integrations that have the category "ERP" and label "paid", plus the Dropbox and Slack integrations:

import prismatic, {
BooleanOperator,
TermOperator,
} from "@prismatic-io/embedded";

prismatic.showMarketplace({
filters: {
marketplace: {
filterQuery: [
BooleanOperator.or,
[
BooleanOperator.and,
[TermOperator.equal, "category", "ERP"],
[TermOperator.in, "labels", "paid"],
],
[TermOperator.equal, "name", "Dropbox"],
[TermOperator.equal, "name", "Slack"],
],
},
},
});

Configure a specific integration

You can use custom UI elements (buttons, divs, hyperlinks, etc.) to trigger integration deployment.

Invoke the prismatic.configureInstance() function from your UI element to display a configuration screen for a specific integration by providing the integration name as integrationName. You can include other display parameters (like usePopover and selector) as described in the iframe injection and popover methods above.

You can also specify an optional skipRedirectOnRemove boolean parameter, which defaults to false. This determines whether users should be redirected to the integration listview upon removing an integration. If you're embedding the marketplace, you likely want to keep this value set to false. If you're implementing a custom API wrapper and handling integration display yourself, you might want to set this to true.

For example, to display the "Salesforce" integration configuration when a button is clicked:

const deploySalesforce = () => {
prismatic.configureInstance({
integrationName: "Salesforce",
skipRedirectOnRemove: false,
usePopover: true,
});
};

<Button onClick={deploySalesforce}>Configure Salesforce Integration</Button>;

For an example of implementing a custom marketplace UI and opening the configuration screen for a specific integration with prismatic.configureInstance(), see GitHub.

Listening to marketplace events

The embedded marketplace emits custom JavaScript events when certain things happen:

  • INSTANCE_CREATED: Emitted when an integration's configuration screen is opened for the first time.
  • INSTANCE_CONFIGURATION_OPENED: Emitted when an instance configuration screen is opened.
  • INSTANCE_CONFIGURATION_LOADED: Emitted when an instance configuration screen has loaded. This is the optimal event to hook into for programmatically setting config variables.
  • INSTANCE_CONFIGURATION_PAGE_LOADED: Emitted when an instance configuration screen transitions between pages.
  • INSTANCE_CONFIGURATION_CLOSED: Emitted when an instance configuration screen is closed (regardless of whether configuration was completed).
  • INSTANCE_DEPLOYED: Emitted when an instance has been configured and enabled for a customer.
  • INSTANCE_DELETED: Emitted when an integration has been deactivated (the instance has been deleted).
  • POPOVER_CLOSED: Emitted when a user closes the popover modal (only applicable when usePopover: true).

You can subscribe to these events to trigger additional actions in your application when instances are created, configured, deleted, etc. All events return data in this structure (except for INSTANCE_CONFIGURATION_LOADED, which includes additional data):

{
"event": "INSTANCE_CONFIGURATION_OPENED",
"data": {
"customerId": "Q3VzdG9tZXI6OThiMjU3MDUtZmMzNC00NWYwLTk0ZDItODA0ZjFkYzEyYTZk",
"customerName": "Smith Rockets",
"instanceId": "SW5zdGFuY2U6YzJlYTliZjEtY2Y3MS00NTg1LTk2MjMtYjZhNDAxYjQyNWRm",
"instanceName": "Salesforce",
"integrationName": "Salesforce",
"integrationVersionNumber": 18,
"readOnly": false
}
}

In this example, we log the customer name and the integration they opened:

import { PrismaticMessageEvent } from "@prismatic-io/embedded";

window.addEventListener("message", (event) => {
// Check if the message event is of type INSTANCE_CONFIGURATION_OPENED
if (
event.data.event === PrismaticMessageEvent.INSTANCE_CONFIGURATION_OPENED
) {
// Extract relevant data
const { customerName, integrationName } = event.data.data;
// Log the customer and integration name. Replace this with your desired data handling or helper functions
console.log(
`${customerName} opened the configuration page for ${integrationName}`,
);
}
});

You can implement similar event listeners for instance configuration page closure, loading, creation, or deletion events.

User-level configuration marketplace events

If user-level configuration is enabled for an integration, the following marketplace events will be emitted:

  • USER_CONFIGURATION_OPENED: Emitted when a ULC configuration screen is opened.
  • USER_CONFIGURATION_LOADED: Emitted when a ULC configuration screen has loaded. This is the best event to hook into for programmatically setting config variables.
  • USER_CONFIGURATION_PAGE_LOADED: Emitted when a ULC configuration screen transitions between pages.
  • USER_CONFIGURATION_CLOSED: Emitted when a ULC configuration screen is closed (regardless of whether configuration was completed).
  • USER_CONFIGURATION_DEPLOYED: Emitted when a ULC configuration is completed.
  • USER_CONFIGURATION_DELETED: Emitted when a ULC configuration is deleted.

For all of these events, the event's data property will contain:

{
"event": "USER_CONFIGURATION_LOADED",
"data": {
"customerId": "Q3VzdG9tZXI6ZjYxMzY4MzItMzYxYi00NmI3LTlmMmItN2ZkNTc3YzY1YTg1",
"customerName": "Smith Real Estate",
"instanceId": "SW5zdGFuY2U6N2I1MjFiNzItYzllNS00YjkwLWIzZGEtZTY4OTY5OWU2ZjBl",
"instanceName": "Dropbox",
"integrationName": "Dropbox",
"integrationVersionNumber": 9,
"userConfigId": "VXNlckxldmVsQ29uZmlnOjI0NDU5MjA2LWQxNGUtNDRhMy04NWE4LTJjMzgwMzg2Y2NmZg==",
"userEmail": "2E52B7CB-071B-4EA2-8E9D-F64910EBDBB1",
"userId": "VXNlcjpmYjc4YzE1OS1kOWMwLTQxMDctYjIyNC0zYmNhMDFlOTQ5NzY=",
"userLevelConfigVariables": {
"Dropbox Connection": {
"status": "ACTIVE"
}
},
"readOnly": false,
"userName": "Phil Embedmonson"
}
}

Dynamically setting config variables in marketplace

consider integration-agnostic connections

If you need to programmatically set connection values, consider implementing integration-agnostic connections, which enable you to configure connections for each customer. You can also use the embedded SDK to set connection values at deployment time, as demonstrated below.

You can programmatically set values for your customers' config variables by leveraging marketplace events. This is particularly useful when you have access to certain values (API keys, endpoints, etc.) and want to set config variables on behalf of your customers (eliminating the need for them to look up these values).

When your application receives an INSTANCE_CONFIGURATION_LOADED event message (or USER_CONFIGURATION_LOADED for ULC), the message payload includes the properties listed above, plus current config variable values.

You can analyze that event's data and conditionally set values for specific config variables using the prismatic.setConfigVars() function. Let's examine the event message structure and how to respond with config variable values:

Here's the structure of the INSTANCE_CONFIGURATION_LOADED payload. The event message's .data.configVars property contains all currently set configuration variables and their values:

Example INSTANCE_CONFIGURATION_LOADED event payload
{
"event": "INSTANCE_CONFIGURATION_LOADED",
"data": {
"instanceId": "SW5zdGFuY2U6ZTE4NTNkYWItZjJhMi00OGIyLTk1ZWItODRjYzQ3YzRiMzc4",
"instanceName": "Test Embedded config vars",
"integrationName": "Test Embedded config vars",
"integrationVersionNumber": 1,
"customerId": "Q3VzdG9tZXI6OThiMjU3MDUtZmMzNC00NWYwLTk0ZDItODA0ZjFkYzEyYTZk",
"customerName": "Smith Rockets",
"readOnly": false,
"configVars": {
"Acme Connection": {
"inputs": {
"username": { "value": "" },
"password": { "value": "" }
},
"status": "PENDING"
},
"My Key/Value List": {
"value": [],
"collectionType": "keyvaluelist",
"codeLanguage": null,
"dataType": "string",
"pickList": null,
"scheduleType": null,
"timeZone": null
},
"My String": {
"value": "",
"collectionType": null,
"codeLanguage": null,
"dataType": "string",
"pickList": null,
"scheduleType": null,
"timeZone": null
},
"My List": {
"value": [],
"collectionType": "valuelist",
"codeLanguage": null,
"dataType": "string",
"pickList": null,
"scheduleType": null,
"timeZone": null
},
"My String With Default": {
"value": "Some Default",
"collectionType": null,
"codeLanguage": null,
"dataType": "string",
"pickList": null,
"scheduleType": null,
"timeZone": null
},
"My List With Default": {
"value": ["Foo1", "Foo2"],
"collectionType": "valuelist",
"codeLanguage": null,
"dataType": "string",
"pickList": null,
"scheduleType": null,
"timeZone": null
},
"My Picklist": {
"value": "",
"collectionType": null,
"codeLanguage": null,
"dataType": "picklist",
"pickList": ["Foo", "Bar", "Baz"],
"scheduleType": null,
"timeZone": null
},
"My Boolean": {
"value": false,
"collectionType": null,
"codeLanguage": null,
"dataType": "boolean",
"pickList": null,
"scheduleType": null,
"timeZone": null
}
}
}
}

The getMessageIframe helper function

Your application needs to identify which iframe to send a setConfigVars message to. Your application might contain multiple iframes, potentially including multiple instances of the embedded marketplace on a single page.

The getMessageIframe function helps identify the iframe that generated the INSTANCE_CONFIGURATION_LOADED event.

If you need to send a setConfigVars message to a specific iframe, you can alternatively provide a selector property to the setConfigVars function (similar to prismatic.showMarketplace()):

setConfigVars message by selector
prismatic.setConfigVars({
selector: "#my-marketplace-container",
configVars: {
"My Config Var Name": { value: "My config var value" },
},
});

Hiding UI elements in marketplace

You can optionally hide the Back to Marketplace link, specific tabs from the instance screen, and elements of the instance configuration wizard. This is useful for preventing customers from running tests from the Test tab or reconfiguring alert monitors independently.

To disable specific UI elements, add a screenConfiguration block to your prismatic.showMarketplace() or prismatic.configureInstance() invocations:

Hide the 'back' link and 'monitors' and 'test' tabs
prismatic.showMarketplace({
selector: `#${id}`,
usePopover: false,
theme: "LIGHT",
screenConfiguration: {
instance: {
hideBackToMarketplace: true,
hideTabs: ["Test", "Logs"],
hidePauseButton: true,
},
configurationWizard: {
hideSidebar: true,
isInModal: true,
triggerDetailsConfiguration: "hidden",
mode: "streamlined", // Hide the initial configuration page
},
marketplace: {
hideSearch: true,
hideActiveIntegrationsFilter: true,
},
},
});
  • instance.hideBackToMarketplace: Controls whether to hide the Back to Marketplace link in the instance configuration screen (defaults to false).
  • instance.hideTabs: Specifies which tabs to hide from the instance configuration screen. Available options are Test, Executions, or Logs tabs. No tabs are hidden by default.
  • instance.hidePauseButton: Controls whether a customer user can pause or unpause an instance.
  • configurationWizard.hideSidebar: Hides the left-hand sidebar from the configuration wizard (config wizard page titles and numbers).
  • configurationWizard.isInModal: Determines whether the config wizard should appear as a modal overlay on the current page. When set to true, it assumes your embedded marketplace is already in a modal (preventing a modal-in-modal scenario) and opens the config wizard to fill its containing <div>.
  • configurationWizard.triggerDetailsConfiguration: Controls the display of trigger details in the config wizard. Options are hidden to completely hide trigger details, default to include the element in collapsed state, or default-open to include the element in expanded state. Endpoint details may also be hidden if they are not configured to be Secured by Customer (see Endpoint Configuration).
  • configurationWizard.mode: Can be set to traditional or streamlined and affects the initial configuration page.
  • marketplace.hideSearch: Hides the search bar in the marketplace.
  • marketplace.hideActiveIntegrationsFilter: Hides the top-right filter for active integrations in the marketplace.

To apply these preferences globally (for multiple showMarketplace() and configureInstance() invocations), configure settings in prismatic.init():

Hide UI elements globally
prismatic.init({
screenConfiguration: {
instance: {
hideBackToMarketplace: true,
hideTabs: ["Test", "Monitors"],
},
},
});

Screen configuration settings in prismatic.init() can be overridden within specific showMarketplace() or configureInstance() invocations. Note that hideTabs properties are not merged in this case - the screenConfiguration settings in showMarketplace / configureInstance completely override the default settings in init.

Integration configuration detail screen

The embedded SDK configuration enables fine-tuning of the user experience for accessing the integration configuration details screen. It includes the ability to prevent marketplace users from accessing the detail screen, which is useful if you want to restrict access to the Test, Executions, Monitors, or Logs functionality.

  • allow-details: Redirects the marketplace user back to the marketplace listing after completing the configuration wizard. When a user selects an integration from the marketplace listing, they see a summary of the integration including its status. Users can manage instances from the overflow menu at the bottom. "View Details" opens the full integration details screen. You can hide specific UI elements on this page. This is the default behavior in SDK version 2.0.0 and later if no configuration is provided.
  • disallow-details: Provides the same experience as allow-details but removes the details option from the overflow menu.
  • always-show-details: Redirects the marketplace user to the full integration details screen after configuration or when selecting an instance from the marketplace listing.
Inline configuration experience that allows marketplace users to access integration config details
prismatic.showMarketplace({
selector: `#my-div`,
screenConfiguration: {
marketplace: {
configuration: "allow-details",
},
},
});

Configuration wizard customization

When customers configure or reconfigure an integration in your marketplace, they will either see an initial configuration page for editing the instance name and viewing webhook URLs, or they will be taken directly to the first page of the configuration wizard. This behavior is controlled by the screenConfiguration.configurationWizard.mode option:

  • traditional: Presents customers with an initial configuration page where they can set the instance name and view general instance details, like flow webhook URLs. This is the default behavior in @prismatic.io/embedded versions before 3.0.
  • streamlined: Skips the initial configuration page. This is the default in @prismatic.io/embedded version 3.x and later.

Note that if you enable multiple instances of your integration to be deployed by a single customer, instance names must be unique. Customers will still see an initial configuration page for editing instance names, but webhook information will not be displayed.

If your config wizard has a single page, the left-hand sidebar displaying config page names will be hidden in streamlined mode.

If you choose streamlined mode but still want to display instance webhook URLs and API keys within your config wizard, you can.

Showing all instances in marketplace

Sometimes you may want to deploy an integration to a specific customer via Marketplace without making it generally available to all customers. To achieve this, deploy an unconfigured instance of the integration to your customer as an organization user. Then, set the filters.marketplace.includeActiveIntegrations marketplace option to true to display instances that are enabled for a customer (even if the integration is not in the marketplace):

Show all instances in marketplace
prismatic.showMarketplace({
selector: `#my-div`,
filters: {
marketplace: {
includeActiveIntegrations: true,
},
},
});
filters take precedence over includeActiveIntegrations by default

Note that if you have filters enabled, the includeActiveIntegrations option will not override the filters. By default, active integrations deployed to a customer must match the specified filters to be displayed.

If you want to display all active integrations regardless of filters, in addition to marketplace integrations that match your filters, set the includeActiveIntegrations option to true and add the strictMatchFilterQuery property set to false.

Multiple instances of one integration in marketplace

By default, customer users can enable a single instance of an integration through the embedded marketplace. However, there are scenarios where you want customers to deploy multiple instances of an integration. For example, your customers might have multiple Shopify stores and require separate instances of your Shopify integration for each store.

Enabling customers to deploy multiple instances of an integration is configured on a per-integration basis. From the marketplace configuration screen or the marketplace drawer in the workflow builder, enable the Allow Multiple Instances toggle.

Allow multiple instances toggle in marketplace drawer

Embedded customer users who select your integration will be able to view existing enabled instances of the integration and will have the option to add additional instances.

Multiple instances in embedded marketplace

Customers will see a similar view if you have enabled multiple instances of an integration for them.

Custom marketplace UI

The embedded marketplace listview screen is presented as an iframe. If you prefer to present marketplace integrations using your own custom UI elements, you can. This is particularly useful if you build some integrations in Prismatic and others outside of Prismatic - you can display both using consistent UI elements.

For complete details, see Custom Marketplace UI.