AddOn Development
- Introduction
- Creating a development app
- Getting started
- Concepts
- Mixed Content AddOns
- The Content dialog method
- The Iframe method
- Configuration parameters
Introduction
Welcome to the BEE Plugin AddOn development documentation!
This document is for anyone that wants to start creating AddOns for BEE Plugin.
Before you get started, you may want to review these frequently asked questions.
Happy coding!
Creating a development app
First, create a development application so that you are not testing your new AddOn with a production application.
Development applications inherit the plan of the production application to which they are connected. You can only build AddOns when you are on the Superpowers plan or above. If you are not on one of those plans:
- Create a development application
- Request an upgrade
Once you have a development application on the Superpowers plan or above, proceed to the next step.
Getting started
The process all starts in the BEE Plugin Developer Portal:
- Log into developers.beefree.io
- If you have not done so yet, create a development app as indicated above
- Click the Details link next to any application on the Superpowers plan or above
- Click the AddOns link, under Application configuration
- Click the Create a custom AddOn button
When you create a new Custom AddOn, you will be prompted to enter some information through the AddOn setup form. Depending on the method that you choose, the number of fields in the form will change.
- Name:
The name of the AddOn saved in the BEE Plugin dashboard. This is not the name that will be used for the tile in the BEE editor’s Content tab, but rather the internal name visible to other developers. In other words, it will not be shown to end-users of the editor. - Enable toggle:
A toggle element to enable and disable the AddOn. When toggled OFF the AddOn is not visible to end-users of the editor in your application (the host application). - Type:
The type of content that the AddOn will create. Currently, the following content types are available:- image
- html
- mixed
- Handle:
A unique identifier for this AddOn. This value will be the future reference between the AddOn and the content on the stage, everywhere from saved rows to templates. Additionally, it will be used to override settings on a per-user basis or to build a content dialog for the AddOn. - Method:
This is an important selection and is covered in detail in the section below.- External iframe: Choose this option if the AddOn is hosted outside of the host application. If this is an AddOn that will be made available to other BEE Plugin applications via the Partner AddOn directory, then it is by definition hosted outside of the host application, and therefore you must select this method.
- Content Dialog: Choose this option for AddOn that live inside the host application (e.g. internal AddOn). You cannot choose this method if you plan to make your AddOn available to others by listing it in the Partner AddOn directory.
- Icon:
Upload an image from your local computer that will become the icon associated with the tile shown in the editor’s Content tab. We recommend a 64 x 64 pixel SVG file. - Labels:
- Title: This is the name that will be used for the tile in the BEE editor’s Content tab (e.g. “Countdown timer”, “Product Recommendation”, etc.).
- Call-to-action button: The label for the call-to-action button (e.g. “Select a Countdown Timer”), which opens the content dialog or iframe.
- Placeholder text: This is the message shown in the editor’s stage when the tile is first dropped into it.
If you are using the iFrame method, some additional fields are shown on the form.
- Iframe URL – Required
The URL that will be loaded inside the Iframe. - API Key – Optional
The API Key used to optionally authorize BEE plugin to load the URL provided above. If authorization is not needed, this field can be left empty. - Authentication URL – Optional
The endpoint that handles the optional authorization request. If authorization is not needed, this field can be left empty. - Healthcheck URL – Optional, but required for Partner AddOns
This URL will be contacted when the editor is started to verify the status of the AddOn. In the case of AddOn downtime, the editor hides it in the UI. Please note: if you are building a Partner AddOn, this is a required field as it will allow applications that have installed your AddOn to protect the quality of their end-users experience if your service is unavailable.
Once you have entered all of the details, click Save, and you should immediately find your AddOn visible within BEE Plugin. However, please note that your AddOn is not completed yet, until you the configuration steps described below are done.
Concepts
Content dialog vs. iframe methods
One of the important choices you will make is in regard to how your content creation AddOn loads.
The general rule of thumb is that if your AddOn lives within the host application, you can use a content dialog.
If your AddOn lives on another website outside of the host app or will be listed in the Partner AddOn directory, then you must select the external iframe method.
Overview of iframe method
The AddOn can be built using any technology stack. There are no specific rules about how your AddOn functions internally.
However, you will need to implement the following:
- JavaScript API
- Protocol to communicate between iframe and BEE Plugin.
- Server API
- Conditional health check endpoint
- Optional authentication endpoint
Don’t worry about the fine details just yet! We’ll revisit each of these methods in more detail in the following sections.
Overview of content dialog method
Superpowers and Enterprise applications have the option to create their own, custom AddOn with content dialogs.
This option is convenient when the AddOn and host applications are hosted under the same domain.
You don’t need to implement a JavaScript API or Server API when using the content dialog.
Content types
An AddOn can only return one type of content. The type you choose will determine which sidebar properties are shown when your AddOn is selected.
Currently, you may choose between the following three types:
- Image:
Will insert an image module on the stage, and show the properties of an image content block in the sidebar. - HTML:
Will insert an HTML module on the stage, and show the properties of a custom HTML content block in the sidebar, except the HTML text input will be hidden. That’s because the HTML cannot be edited outside of the content dialog or iframe made available by your AddOn. - Mixed:
Will insert a module on the stage that allows for loading of different content blocks with a single action.
Mixed Content AddOns
Mixed Content AddOns are a new type of content tile that allows the host application to load multiple content modules at once. This grants you greater flexibility with how you want your custom AddOn to interact with your customers and data; for example, you could create a mixed content AddOn to drop a product image in your template, along with a title, description, and more.
To utilize this new feature, it is necessary to:
-
Create a new custom AddOn of type “Mixed Content” from developers.beefree.io, as described in the “Getting started” section of this article;
-
Add the integration code required by custom AddOns (for example, if the user chose the “Content Dialog” method, it might look something like this):
1 var beeConfig = { 2 ... 3 contentDialog: { 4 addOn: { 5 label: 'Custom AddOn Label', 6 handler: (resolve, reject, args) => { 7 ... 8 } 9 } 10 } 11 }
- The host application should return a valid response as the parameter of the “resolve” callback.
Response Content
A valid response that the hosting application should send to the Plugin when the contents of a Mixed Content AddOn are selected must have the following structure:
{
"type": "mixed",
"value": [
... here the list of modules
]
}
For example:
{ "type": "mixed", "value": [ { "type": "title", "value": { "text": "Enjoy $50 off!", "title": "h1" } }, { "type": "title", "value": { "text": "ENTER CODE: 2 YEARS", "title": "h2" } }, { "type": "image", "value": { "alt": "My custom image", "href": "http://www.google.com/", "src": "http://my-image-url", } }, { "type": "button", "value": { "label": "SHOP NOW >", } } ] }
If the response is not valid, an error is raised, and onError
is called.
Modules definition
For each module type, here is the list of allowed properties.
Unless otherwise specified, the properties are optional.
title
- “text”: string (e.g., “this is the title content”)
-
“title”: string (e.g., ex. “h1”)
image
-
“alt”: string
-
“href”: string (e.g., “http://www.my-website.com”)
-
“src”: string (e.g., “http://www.my-website.com/my-image.png”)
-
“dynamicSrc”: string (e.g., “{{my-merge-tag}}”)
button
-
“label”: string (e.g., “my button content”)
-
“href”: string (e.g., “http://www.google.it/”)
paragraph
-
“html”: string (e.g., “this is the <b>paragraph</b> content”)
list
-
“tag”: string (e.g., “ol” or “ul”) (THIS IS MANDATORY)
-
“html”: string (e.g., “<ol><li>first</li><li>second</li></ol>”)
icons
“icons”: [{
“image”: string (for ex. “http://my-image-url”) (THIS IS MANDATORY)
“textPosition”: string (for ex. “right” “left” “top” “bottom”) (THIS IS MANDATORY)
“text”: string
“alt”: string
“title”: string
“href”: string
“target”: string (for ex. “_blank”)
“width”: string (for ex. “200px”) (THIS IS MANDATORY)
“height”: string (for ex. “200px”) (THIS IS MANDATORY)
}]
As an example, here is a response that contains at least one occurrence for each module type:
{ "type": "mixed", "value": [ { "type": "title", "value": { } }, { "type": "title", "value": { "text": "This is an H1 block", "title": "h1" } }, { "type": "title", "value": { "text": "This is an H2 block", "title": "h2" } }, { "type": "title", "value": { "text": "This is an H3 block", "title": "h3" } }, { "type": "image", "value": { } }, { "type": "image", "value": { "src": "http://my-image-url", } }, { "type": "image", "value": { "alt": "My custom image with dynamicSrc", "href": "http://www.google.com/", "src": "http://my-image-url", "dynamicSrc": "{{any-merge-tag}}" } }, { "type": "button", "value": { }, }, { "type": "button", "value": { "label": "AddOn custom Button", "href": "http://www.test.com", } }, { "type": "paragraph", "value": { } }, { "type": "paragraph", "value": { "html": "AddOn custom Paragraph" } }, { "type": "list", "value": { "tag": "ul", } }, { "type": "list", "value": { "tag": "ol", "html": "" } }, { "type": "icons", "value": {}, }, { "type": "icons", "value": { "icons": [] }, }, { "type": "icons", "value": { "icons": [{ "image": "http://my-image-url", "textPosition": "right", "text": "Custom AddOn icon text", "alt": "Custom AddOn icon alt", "title": "Custom AddOn icon title", "href": "https://www.google.com", "target": "_blank", "width": "100px", "height": "100px", }], } }] }
- AddOn custom List item
The Content dialog method
To set up the content dialogs you will need to add the contentDialog object to beeConfig. For more details about the content dialog, please review Content Dialog: How it works.
Configure content dialog in beeConfig
contentDialog: { addOn: { handler: (resolve, reject, args) => {}, }, },
Returned value syntax
Image
{ "type": "image", "value": { "alt": "Alternative desc", href": "http://www.example.com/", "src": "https://d1oco4z2z1fhwp.cloudfront.net/templates/default/731/HNY2020.gif" "dynamicSrc": "{{any-merge-tag}}" } }
HTML
{ "type": "html", "value": { html: '', } }
The Iframe method
JavaScript API
General
The JavaScript API allows an application inside of an external iframe to communicate with the host application that’s embedded BEE Plugin. If you use the content dialog option, there is no need to implement the JavaScript API.
This section describes the communication protocol between BEE Plugin and an external AddOn (i.e. an AddOn that is loaded into an iframe inside BEE Plugin).
The communication takes place using postMessage, which is a standard way of communicating between Window objects.
The data object sent in the messages exchanged between the plugin and the AddOn has a standardized form:
{ action: string, data: any }
Actions
The application inside the iframe may trigger the following actions:
- onCancel
- onSave
Events
The application inside of the iframe may listen for the following events:
- loaded
- init
- load
Protocol
BEE Plugin creates an iframe for the AddOn and then expects it to start the conversation by sending the loaded action:
{ action: 'loaded' }
The AddOn may also pass optional arguments to define the shape and style of the modal dialog that will contain the AddOn. If no arguments are provided the modal will fill the screen with no border.
The following parameters are available for the loaded method:
- isRounded: Boolean true or false value. If true, the modal will have rounded corners.
- hasTitleBar: Boolean true or false value. If true, the modal will display a title bar.
- showTitle: Boolean true or false value. If true, the name of the AddOn will display in the title bar.
- width: The width of the modal in pixels. If not provided, the modal will be 100% width.
- height: The height of the modal in pixels. If not provided, the modal will be 100% height.
The following is a full example of a fixed-size modal with rounded corners, no title, and no close button. In this case, a custom close button is provided by the AddOn using the onCancel method.
window.parent.postMessage(
{
action: 'loaded',
data: {
isRounded: true,
hasTitleBar: false,
showTitle: false,
width: '820px',
height: '640px'
},
},
'*'
)
The Plugin then responds with an init message that contains the current locale of the editor and any pass-through data defined by the host application:
{ action: 'init', data: { locale: 'current plugin locale', data: { ... sent by host app } } }
This message may be followed by an optional load message from the Plugin in case the user has already defined the content of this AddOn in a previous session:
{ action: 'load', data:}
Any further action is then on the AddOn. In case the user cancels the edit, it is expected to send an onCancel message:
{ action: 'onCancel' }
And if the user finishes editing and clicks on the save (or OK) button, the AddOn is expected to send an onSave message:
{ action: 'onSave', data: { type: 'html | image', value:} }
Server API
The Server API is only for use with external iframe applications. The application inside of the iframe must implement at least one API endpoint for a health check, but may also implement an optional endpoint for authentication. If you use the content dialog option, there is no need to implement the Server API.
Healthcheck
The health check endpoint is mandatory for apps that will be posted to the partner directory but otherwise optional. If your AddOn is for internal use (i.e. a custom AddOn), then you can perform your own health checks inside of the host application. If the application is offline, then you can use the configuration settings to disable it. If you choose to implement the health endpoint, simply ensure it returns a 200 for all GET requests.
Authentication
An application is not required to use any authentication. For example, the Giphy AddOn by BEE Plugin is FREE for all users and therefore has no need for authentication.
However, authentication can be enabled for applications of any kind, if you want to identify or authorize the user to access your resources.
To enable authentication, simply add the optional parameters to your AddOn in the Dev Portal:
- API Key:
This is any globally unique identifier that can be used to identify the customers, but usually, this would be a bearer token or JWT. - Authentication URL:
This is the URL of your authentication endpoint. More on this below.
Protocol
With authentication enabled, a specific protocol follows:
- Before the BEE Plugin creates an iframe for the AddOn, it performs a proxied GET request to the authentication URL.
- The following HTTP Headers are passed to the AddOn’s endpoint.
- x-real-ip:
The IP Address of the host application - authorization:
It contains the API Key (e.g. bearer token), which you provided to the host application. - x-bee-clientid:
It contains the client id of the host application. - x-bee-uid:
It contains the uid defined in the BEE configuration.
- x-real-ip:
- The iframe application uses the Authorization Header to validate the user permissions.
- In the event of success, the application returns a URL to load within the iframe. The URL is provided as plain text with a 200 status code, no JSON formatting is needed.
- In the event of unauthorized, the application returns a 403 status code.
- BEE plugin creates an iframe for the AddOn using the URL returned from the authorization endpoint.
- The AddOn application loads the application or performs additional authentication.
Configuration parameters
Once you have initialized BEE Plugin, you can pass a series of configuration parameters to it.
The AddOn section of the configuration allows you to override the parameters you configured at the application level, on a per-user basis.
See: Adding client-side configuration parameters for AddOns.