Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
This feature is available on Beefree SDK Core plan and above. If you're on the Essentials plan, upgrade a development application for free to try this and other Core-level features.
There are three types of pre-built reusable content you can provide your application's end users with. These are the following:
In this page, we will look at a sample rowsConfiguration
that incorporates defaultRows
, emptyRows
, selectedRowType
, and externalContentURLs
. The Implement Custom Rows page will discuss the steps to integrate Custom Rows.
The following code snippet provides a sample rowsConfiguration
.
This section explains each of the properties listed in the rowConfiguration
code snippet.
These properties are the following:
emptyRows
: Set of empty rows. The same rows available when rowsConfiguration
is not included. End users can use these empty rows to structure and customize their own content within.
defaultRows
: A set of rows that contain sample content. End users can use the sample content as inspiration for customizing them with their own look and feel.
selectedRowType
: Specify which type of row should be pre-selected when the end user opens the Rows selection in the visual builder.
externalContentURLs
: Each item in this list defines an option available in the Rows tab drop-down.
You can add pre-built default rows to your builder by setting the defaultRows
property to true
in your beeConfig
.
Default rows are a set of rows that contain sample content. That’s why we also call them sample rows. They may be used as a supporting feature for starting templates, or to speed up the process of building a message from scratch.
Allowed values: boolean
, can be set to true
or false
.
Default value: false
They are presented as follows in the builder’s default theme (the screenshot shows the first 2 default rows):
You can add pre-built empty rows to your builder by setting the emptyRows
property to true
in your beeConfig
. Empty rows are a set of rows that aren't prefilled with content. However, they offer a general structure for content to be placed within them. These are the same rows available to end users when the rowsConfiguration
parameter is not included in the beeConfig
.
Allowed values: boolean
, can be set to true
or false
.
Default value: true
Will always be included as the last element if omitted in the configuration.
They are presented as follows in the builder’s default theme (the screenshot shows the first 4 empty rows with unique structures):
This property is used to specify which type of row should be pre-selected when the end user opens the Rows selection in the visual builder. You have several options for what value to assign to this property, and its role is to simplify the end user's interaction with the builder by focusing their attention on a specific type of row by default.
Possible values for selectedRowType
:
'defaultRows'
: This value will automatically select the default rows that come with the builder, which usually contain pre-designed content that users can easily modify and adapt. It helps users start with a pre-configured structure and quickly adjust it to meet their needs.
'emptyRows'
: This value pre-selects an option for the user to start with empty rows. This is useful for users who prefer to build their layouts entirely from scratch, without any predefined content or structure.
The handle of a row in externalContentURLs
:
You can also pass the handle of a row that is listed in externalContentURLs
to pre-select a row from an external source. A handle in this context refers to the unique identifier or name used to reference a specific row from an external list. Think of it as a unique key that allows the system to identify which external row to load or pre-select.
For example, if you have external content rows listed in externalContentURLs
, such as "Rows list 01" or "Rows list 02," you can pass their respective handle (typically a string like "Rows list 01"
) as the value for selectedRowType
. This will automatically load and pre-select that specific external row, saving the user the step of manually selecting it from the list.
The externalContentURLs
property accepts a row's name and url. You can add multiple items to the property. Each item in the list defines an option available in the Rows drop-down.
name
: the text displayed in the Rows drop-down
value
: URL that will be called by the builder when the user selects the corresponding name in the drop-down. The URL must return a set of rows as a JSON object.
The following image displays an example of how the name
value appears in the drop-down menu.
In the drop-down menu, you can see a visual example of each pre-built content type mentioned in this article and in Implement Custom Rows:
Empty rows: When the end user clicks the Empty option in the drop-down menu, they will be redirected to a list of row structures to choose from.
Default rows: When the end user clicks the Default option in the drop-down menu, they will be redirected to a list of default rows to choose from.
My Saved Rows: When the end user clicks the My Saved Rows option in the drop-down menu, they will be redirected to a list of rows they created and saved to reuse at a later time.
Custom rows: The MailChimp Footers, HubSpot Footers, and Sendgrid footers are additional options added to the drop-down through the Custom Rows feature. When an end user clicks on any of these three options, they will be redirected to the lists of rows available in that external resource.
A handle acts like a reference key to point to a specific row in an external list. Handles are typically unique names or identifiers that can be used to quickly access specific rows from an external content source, ensuring that the correct row is fetched and displayed to the user. For instance, in the following configuration:
If you want to pre-select "Rows list 01" from the external content list, you would set selectedRowType: 'Rows list 01'
, where 'Rows list 01'
is the handle of that specific external content row. The handle here refers to the name or a unique identifier that the system recognizes and uses to select the correct row from the external content list.
Visit Manage Reusable Content to learn more about editing, deleting, categorizing, and managing rows within the builder.
This feature is available on Beefree SDK Core plan and above. If you're on the Essentials plan, upgrade a development application for free to try this and other Core-level features.
This page provides an overview of Saved Rows and their key benefits.
Saved Rows in Beefree SDK optimize the content creation process by allowing users to save, categorize, and manage reusable rows for future use. When this feature is enabled, users can simply click the Save icon on a row within their design and store it for later. This ensures quick access to preferred layouts and design elements across multiple projects.
Reusable Rows: Save rows once and reuse them across multiple designs.
Flexible Categorization: Organize rows into intuitive categories for discoverability.
Easily Manage Rows: Manage rows with intuitive editing options.
Enhanced User Experience: Enable users to save, categorize, and manage their rows efficiently.
Flexible Implementation and Management Options: Activate, store, and manage Saved Rows using either hosted or self-hosted options.
Highly Customizable: Enable or disable end user permissions to delete, edit, manage, or add Saved Rows.
When enabled, Saved Rows allow end users to select a row in their design and save it. This process involves:
Selecting a row in the builder.
Clicking the Save icon in the toolbar or row properties panel.
Storing the row’s structure, content, and styles as a JSON document in your chosen storage solution.*
*Beefree SDK offers two paths for this: Hosted Saved Rows or Self-hosted Saved Rows.
Saved Rows are displayed in the builder’s Rows panel. Users can:
Browse saved rows by category.
Search for rows using metadata like row names or descriptions.
Drag and drop rows into their designs for immediate use.
There are two paths you can take to activate Saved Rows for your application:
Hosted Saved Rows
Self-Hosted Saved Rows
Both paths provide their own set of benefits. The following section discusses these activation paths at a high-level. For more detailed information on both activation routes, reference Implement Hosted Saved Rows and Implement Self-Hosted Saved Rows.
Saved Rows can be hosted and configured using one of the following options:
Fully managed by Beefree SDK, and activated through a toggle in the Developer Console.
Ideal for teams that want a quick setup without maintaining backend systems.
Offers centralized storage, security, and reliability, while also providing a user interface to save and reuse rows within your application.
Allows full control over where and how rows are stored.
Suitable for teams with specific compliance or integration needs.
Requires development resources for managing row storage, and creating a user interface to manage and reuse rows.
Learn more about Storage for Reusable Content.
Save a footer row with contact details, social media links, and copyright information. Use it across multiple email templates to ensure consistency.
Create reusable rows showcasing product images, descriptions, and call-to-action buttons. Pull these rows dynamically from an e-commerce catalog for up-to-date content.
Save promotional rows with pre-configured styles and messaging. Reuse them across campaigns to maintain branding and reduce setup time.
If you're on the Essentials plan, upgrade a development application for free to try this and other Core-level features.
Synced Rows expands on the foundational capabilities of Save Rows and Edit Single Row Mode, helping users manage rows more effectively. Using the merge-rows
and synced-rows
methods in the Content Services API (CSAPI), you can create an efficient row management workflow. This ensures that when users update content in one row marked as “synced,” those updates are reflected across all connected designs using that synced row.
Cross-design synchronization: Sync saved row contents across multiple linked designs.
Design consistency: Lock rows in linked designs to keep designs uniform.
Editing flexibility: Convert rows from synced to unsynced, making individual changes as needed.
Intuitive edit indicator: Look for the pencil icon at the top-right of synced rows, which provides access to editing options
Auto-updating contacts: Change a contact in one email, and it updates across multiple campaigns.
Effortless re-branding: Edit your logo once and watch it reflect across all designs.
Unified transactional footers: Update details like copyright or social links, and it automatically updates in all relevant email templates.
Row details: This includes structure, settings, and styles.
Content details: Settings and styles of individual content blocks.
Metadata: Any metadata tied to the saved row.
With Edit Single Row Mode you can offer an easier way for your end users to modify a single row with a tailored UI built to edit the row structure, content, and style settings without interfering in the overall design of the email campaign, landing page, or pop-up.
Edit Single Row mode complements both Saved Rows and Synced Rows, because it allows complete control over the content of an individual row (for example, a footer that requires an update) without the need to intervene in a full template's design. This will help you in implementing a more effective way to manage libraries of Saved Rows and Synced Rows with a streamlined design and editing process.
This feature is available on Beefree SDK Core plan and above. If you're on the Essentials plan, upgrade a development application for free to try this and other Core-level features.
Our builders offer ready-to-go rows to your end-users, which provide both structure and content to create contents faster. With Edit Single Row mode you can offer an easier way for your users to modify a single row with a tailored UI built to edit the row structure, content, and style settings without worrying about messing up with the overall design of the email campaign, landing page, or pop-up.
Edit Single Row mode complements the Saved Rows as it allows a complete control over the content of individual rows (e.g. the footer that requires to be updated) without the need to intervene into a full template, this will help you in implementing a more effective way to manage libraries of Saved Rows with a streamlined design process.
When a builder application is initialized with this mode enabled the UI will show to the user only properties that pertain to editing a single row, therefore:
the options to insert custom rows, saved rows, or new default rows are disabled,
the Settings tab is unavailable, as those properties are specific to the entire document,
when a row is selected on the editing stage, the action to Delete, Duplicate, Comment, Save are not available.
The following describes the recommended workflow to implement the Save action in your host SaaS application when the Single Edit Row mode is enabled.
In case your application uses the default Toolbar, you can leverage the save button to trigger the sequence of action to correctly save the row, the workflow is the same as the one documented in saving-rows-workflow-for-developers, in short :
The user clicks on the save button
A contentDialog of type saveRow will be triggered.
In case your application doesn’t use the default Toolbar you will need to handle the row saving in a different way, following a couple of examples:
Calling the save method. It will trigger the on onSave event with two arguments, one of them is the full message JSON that can be saved as a Saved Row (it’s the same JSON returned by the onSaveRow event).
Listening to the onChange event. It will receive the updated full message JSON which again can be saved as a Saved Row.
An effective way to update saved rows across multiple templates is by implementing the save action in combination with the CSAPI, to handle a row update across multiple existing templates.
This feature is available on Beefree SDK Core plan and above. If you're on the Essentials plan, upgrade a development application for free to try this and other Core-level features.
Beefree SDK offers a comprehensive suite of features that enable your application's end users to save and manage reusable content. Rows are a core feature of the visual builders within Beefree SDK that provide end users with an intuitive avenue for saving and reusing content throughout their design creation workflows. They provide a structured method to house various types of content such as headers, paragraphs, images, and buttons.
Rows are also a fundamental part of how designs are built and structured within the visual builders. In the following GIF, you can see how each row functions as a component of a continuous design.
Rows allow end users to add multiples types of content to a section of a design. End users can either create their own rows from scratch (and save them for reuse on a later day), or they can use pre-designed rows that are pre-loaded into the host application and ready for use. Pre-loaded rows are helpful when providing a template structure that end users can customize as they build their designs.
Providing end users with the option to easily reuse content comes with a host of benefits, including:
Pre-designed and customizable content: End users can select from rows that already contain content, which they can then customize for their specific needs.
Flexible structure: Rows help organize different content types in a structured layout, which promotes a clean and efficient design.
Drag-and-drop functionality: Rows can easily be dragged and dropped onto the stage.
Continuity with current user experience: End users can add empty structures, which preserves creativity and allows them to build and design from scratch.
Option to disable empty rows: If preferred, end users can opt to work solely with pre-made rows, focusing on content customization without the need to build layouts from the ground up.
In addition to rows offering a variety of benefits for end users, there are also clear benefits for the host application, including:
Ready-to-go content delivery: The host application can pass pre-built, ready-to-go rows directly into the builder, reducing the need for end users to create content from scratch.
Customization control: Host applications can offer a variety of customizable rows, ensuring users follow design guidelines while still providing creative freedom.
Improved user experience: Pre-designed rows simplify the user interface, making the builder more intuitive and less complex for users.
Optional removal of empty structures: Host applications can disable empty row options if desired, encouraging users to focus on modifying pre-existing content.
Efficient content management: Rows enable the host to provide consistent, reusable content blocks that can be updated globally, streamlining content management and maintaining design consistency across the platform.
This section outlines the different row-related features available within Beefree SDK. Throughout the following pages of the Rows section, we will discuss each of these different row-related features in depth, including what they are, how they look, and how to implement them if they are a good fit for your application and end users.
The purpose of Custom Rows is to provide pre-configured rows that your end users can drag-and-drop into the builder and start customizing.
The following GIF provides a visual of how Custom Rows look to end users:
Custom Rows are integrated by adding the rowsConfiguration
parameter to your beeConfig
. The following code snippet is the one used to configure the row in the GIF above.
Visit the Beefree SDK playground to experiment more with the Custom Rows configuration, and visit the Implement Custom Rows page to learn more about integrating this feature within your application.
Hosted Saved Rows allow your end users to save and manage their own rows to be used later–a powerful way to help them streamline their workflows!
Also, Hosted Saved Rows simultaneously provides both a storage solution and user interface your application's end users can engage with to save and manage their rows.
In the following GIF, with Hosted Saved Rows, Beefree SDK provides the user interface and infrastructure to power Saved Rows so you can bring this feature to your end users instantly.
Implementing Hosted Saved Rows takes only a few seconds, because it activated through a toggle in the Beefree SDK Developer Console. The following image shows how the toggle looks like in the Developer Console.
Visit the Implement Hosted Saved Rows page to learn more about customization options and integration details.
Self-hosted Saved Rows are similar to Hosted Saved Rows on the frontend, but require you to connect your own database on the backend. This feature also provides you with more customization options on the frontend if you'd more granular control over customizing your end user's experience saving and managing rows.
The following GIF shows an example of a customized modal for saving a row within an application. This modal uses both saved rows and content dialog for the customized experience.
Note: Unlike Hosted Saved Rows, Self-hosted Saved Rows does require development.
The purpose of Synced Rows is to maintain consistency by synchronizing row updates across multiple designs. A synced row can be reused across multiple designs and each design is updated whenever a synced row is updated. When you edit a synced row, you a redirected to Edit Single Row Mode.
The purpose of Edit Single Row Mode is to allow precise editing of rows inside of a dedicated row builder. The GIF above displays an example of Edit Single Row Mode. Visit Initialize Edit Single Row Mode to learn more about how to implement this feature.
Custom Rows are a powerful way to provide “ready-to-go” content directly into the builder. Think products, blog articles, events, coupons. And don’t forget that Saved Rows your customers might have will be loaded as Custom Rows the next time they load the builder.
All this content is crucial to make the most out of the Beefree SDK experience, and that’s why you can add UI elements in your app’s interface to:
jump right to a Custom Rows category, without the need for the user to go into the Rows tab, click on the dropdown and select the category;
provide additional information on the available rows, either through a tooltip or by showing a Content dialog with all the information and the links to the rows.
With this feature, you will reduce the friction needed to discover and access the builder’s Custom Rows. To do so, you’ll use the loadRows
event, which will trigger the Custom Rows content dialog.
Here’s an example of our Beefree product, which integrates Beefree SDK, taking advantage of this method to load custom rows from its UI.
The toolbar in the application contains explicit call-to-action text links to load footers, which correspond to different categories of Custom Rows in the application.
When users click on “Mailchimp Footers”, the Custom Rows Content Dialog is triggered, meaning that the builder opens a communication channel with your application. In this case, no additional UI will be displayed, as the host application provides the URL to the rows associated with that call-to-action. This way, the Rows tab will be immediately selected, with the “Mailchimp Footers” category already selected:
But what if you wanted users to select the email footers they need from a large catalog of pre-built content? In that scenario, you could have a more generic “Load footers” call-to-action in the toolbar.
Clicking on “Load Footers” will once again trigger the Custom Rows content dialog, but this time the application could provide a dialog window where users can browse or search through available footers, and get some additional context on them. Here is a visual example of how it might look like, but as with all content dialogs you have complete freedom on what to show:
When users click on MailChimp, the modal window fades off, the builder switches to the “Rows” tab, and the MailChimp Footers are shown, ready to be dragged into the message.
You can trigger the Custom Rows content dialog via the loadRows
instance event.
Once the Content Dialog is triggered, you have two options, as explained in the How it works section:
Interact with the end user, as described in our Content Dialog documentation, and eventually return a URL of custom rows.
Immediately return the rows URL, without displaying the Content Dialog. This is useful if you have a menu and already know which rows to load based on the interaction by the end user with you application’s UI.
Content Dialog allows you to build user interfaces that let your users locate & insert additional content (Custom Rows) while they are working on their message.
By letting you establish an interaction layer between the editor and your application (e.g., you show a modal window), it allows your users to locate/build/insert new rows, thus making the Rows tab in the editor dramatically more flexible and scalable.
Note that Content Dialog may be used to load other content types, as merge tags, special links, or display conditions. Learn more about the Content dialog.
To start using it, you need to add the contentDialog object to beeConfig, or add the externalContentURLs parameter if you already use this feature in your editor configuration.
Here is an example of the syntax that needs to be added to the editor configuration document (beeConfig):
From the perspective of your users, this additional configuration adds a new item (using your text label) in the Rows drop-down.
Here is a visual example of how the “Search products” label will be shown, at the bottom of the Rows drop-down.
When the user clicks on the new menu item (e.g., “Search products” in the example above), what you define in the handler (a function with a Promise-like signature) is triggered.
You can use this event to display a form where the user can search for new items to insert in the message. Here is a visual example:
You could also ask the user to enter parameters that will affect the very structure of the rows (JSON documents) that will be imported into the editor, affecting the way they will display:
You can also mix both forms in a 2-step pattern.
When the selection is made, you must return to the resolve function a URL containing the result (row’s list).
The response must match the same format used to define the externalContentURLs in beeConfig:
This response will:
Create a new drop-down choice with the provided name
Display the rows provided by the URL in the rows panel
Notice that in the rows list, names returned by the Content Dialog display as highlighted elements to give them further visibility over starting choices.
The Content Dialog can be used as many times as the user needs and, depending on the response, the behavior may change:
This overwrites the existing results, keeping the same name in the drop-down. This behavior perfectly matches our example above, where the host application returns “Your search results” every time the content dialog is resolved.
This creates a new drop-down choice, keeping the previous results as selectable elements. Previous results are available directly in the drop-down.
Here is a visual example:
In our example, we are using this event to display a search form and transfer the user selection to the editor as custom rows.
The form is part of the application, so we are using the same elements and styles that users of the application are used to.
Rows can be saved directly in the editor using the Save Rows feature. These rows are returned to the host application as JSON objects that you can store based on your application logic.
These same rows can then be fed back into the editor by leveraging Custom Rows.
To do so, the host application must make them available in a reachable location specified through the externalContentURLs parameter.
The rows are displayed based on your rows configuration, so you can categorize them, creating multiple lists of rows to improve the user experience.
Here is an example of a rows configuration that displays saved items divided into usage categories:
And here is another example where saved rows are organized based on the campaign type:
The following is an example of the response schema when the editor calls one of the provided URLs:
With the introduction of Saved Rows Management, we’ve also introduced the ability to load external rows with an instance method. See here for more details.
This feature is available on Beefree SDK Core plan and above. If you're on the Essentials plan, upgrade a development application for free to try this and other Core-level features.
Saved Rows allows end users to select a row in a design and save it for later use. More specifically, it allows end users to submit a request to the host application to save a piece of content and turn it into a reusable element. The host application, using externalContentURLs
, can feed these saved elements back to the builder as rows that can be dragged into other designs.
In the following video tutorial, you will learn how to implement Self-hosted Saved Rows in an application that has embedded Beefree SDK.
You can also reference the sample code in our GitHub repository used throughout this video.
When the Self-hosted Saved Rows feature is enabled, a Save icon is added to the action icons when a row is selected. The following image displays an example of a row with the Save icon enabled in the upper right-hand corner.
The Save icon is also available in the Row properties panel when a row is selected. The following image displays an example of this.
By clicking on the Save icon, the end user triggers a request to the host application to store the row’s JSON document.
This JSON document includes the following:
Row structure and settings.
Contents and their settings.
All style settings.
The host application needs to determine the following:
Where to store the JSON documents that describe these saved rows.
If and how to display them to end users of the application.
Whether to allow end users to edit them individually.
When and how to feed them back to the builder, using the externalContentURLs
parameter.
Take the following steps to enable Self-hosted Saved Rows in the Beefree SDK Developer Console:
Log in to the Beefree SDK Console.
Locate the application you'd like to activate Self-hosted Saved Rows for.
Click the application's corresponding Details button.
You will be prompted to the Application Details page.
Click the View more link under the Application configuration heading.
Navigate to the Saved Rows section.
Toggle on the Self-hosted on your own infrastructure option.
Click Save on the upper right-hand corner to save your changes.
The following image displays where the toggle is located in the Beefree SDK Developer Console.
Once the feature has been turned on at the global level, in Beefree SDK Console, you may want to disable Saved Rows on a per-user basis. This can be accomplished via the client-side configuration document that you feed to an application when initializing the builder for a certain user.
Why? Because you may decide to make the feature available to different users of your application:
depending on the subscription plan that they are on (you could push users to a higher plan based on the ability to save a row for later);
depending on the purchase of an optional feature (same);
to allow “beta” users to see it while keeping it hidden from the rest of your users;
etc.
Here’s how to do so:
Enable Saved Rows in the Beefree SDK Console. as mentioned above.
Add the configuration parameter saveRows to the beeConfig document:
Set it to false for all users that cannot saved rows.
Here is a simple example:
Visit the Saved Rows section of the Reusable Content page to learn more about the end user experience with saved rows. You can also reference the white label end user documentation on Saved Rows to learn more.
The following GIF provides a quick visual example of the end user experience:
When the saved row action is triggered by the user, the builder starts the following sequence:
Metadata Content dialog Used to collect data from the host application and add it to the row object. Metadata helps your application to identify a row, overwrite a previously saved version, etc.
Saved Rows Callback. Function that returns the row to the host application.
The following describes the recommended workflow to implement saved rows in a host SaaS application.
Enable Saved Rows in the Beefree SDK Console as described above.
Load a Beefree SDK template.
Select the row you want to save and make note of the new save icon.
Click the save icon to trigger a Metadata Content Dialog. To successfully handle this step, you must complete these tasks:
Add a Metadata Content Dialog object to your beeConfig. This configures your handler.
Implement the handler method to open a dialog (e.g., modal window) to collect any metadata you wish your users to input when saving a row.
The dialog should contain a form and complete the following specs:
Save the row returned in the Metadata Content Dialog’s args object.
Collect metadata from the end-user, such as row name.
Merge the metadata with the row, so it can be immediately returned to the application.
Return a metadata object to the application so the stage can immediately use the data.
The application will update the selected row on the stage with the returned metadata.
The application will trigger the onSaveRow callback with the following details:
JSON of the selected row
HTML preview of the selected row
Page Partial of the selected row contained in a page. Use this JSON document to allow users to edit a saved row independently of any message or landing page that might use it.
The application will refresh the Rows panel to reload the selected rows data feed.
Host app will listen for onSaveRows callback and update the previously saved records with the HTML preview.
To display saved rows in the Rows tab, add them to the list of rows available to users by leveraging Custom Rows.
The rows are organized in lists that are displayed based on your rows configuration. Use the metadata submitted by your users to categorize them, creating multiple lists of rows: this can significantly improve the user experience.
The following code sample shows an example of a rowsConfiguration
that displays saved rows organized by category:
In this code snippet example, the Rows tab will show:
Empty rows
Default rows
Headers
Footers
Product grids
Main article
… retrieving the arrays of JSON documents for custom rows (externalContentURLs) from the URLs specified.
These custom rows names (Headers, Footers, Product grids, etc.) could be the result of a “Category” metadata entered by the user at the time the row was saved. The input could be the result of:
The user writing a new category name for the selected row.
The user selecting from a list of existing categories, previously created by the user, or set up by you.
Here is another example that shows saved rows organized in the Rows tab based on the campaign type:
You can set a category's maximum rows using the following configuration"
For more information on setting a category's maximum rows, visit Manage Reusable Content.
Accessing, and organizing saved rows is intuitive with Saved Rows Management. With this feature, we’ve introduced a new action in the list of saved rows that your application can intercept to handle changes in this list itself. This means you can now delete, rename, or re-organize your saved rows, right inside the builder.
Visit the Saved Row Management Actions section of the Manage Reusable page to learn how to configure edit and delete row options for your application's end users.
Saved Rows Management also comes with the ability to load any external rows via an instance method instead of an external URL. In addition, since you can now access rows through your application, you don’t need to perform authentication.
To start, define a hook in your application configuration. The hook method should be named getRows
and will be nested under the hooks
object, as follows:
Following that, amend your rowsConfiguration
object with the additional parameters:
The handle
parameter to utilize in your getRows
handler from the previous step
The isLocal
parameter to let the application know to use the hook handler
When the getRows method is invoked, utilize the 3rd parameter to obtain an argument containing the handle value of the row being requested. Use the handle to determine which set of rows should be returned.
Finally, we can call the resolve method, passing in an array of savedRows.
If you are using a React application, be sure to pass a new rows array and not a reference to a row state. Otherwise, the rows state may be “stale” and won’t update in the side panel.
The following is the basic structure of the row’s JSON schema. Simply put, the schema is the structure of your saved rows data feed.
NOTE: The row schema is complex and we do not recommend creating rows programmatically. Therefore, there is no schema reference of the row itself. However, you can add your own parameters to the row’s metadata or use our Simplified Row Schema to generate them programmatically from existing content.
The metadata section of the rows schema allows you to keep track of row-specific information.
A string of plain text that identifies the row.
Displayed in the row card when the row is shown in the Rows panel.
Used for text searches within the Rows panel
category A category can be useful for organizing your feeds on the Rows tab.
id A handle that identifies the row in the host application’s data storage.
idParent Useful to track rows that were saved from previously saved rows. Keeping track of where a row came from allows you to implement additional editing features.
dateCreated The date the row was created: useful for filtering/sorting rows for content management purposes in your application. It can also help with technical support tasks.
dateModified The date a saved row was updated: useful for filtering/sorting rows for content management purposes in your application. It can also help with technical support tasks.
userId To let your application decide whom can edit or saved rows.
tags Useful to create filters, management, search, and in general to organize the content in your application.
The metadata content dialog is triggered by the save icon in Beefree SDK. This step is required to provide Beefree SDK with information about the row, such as its name and/or id. The Metadata Content Dialog is added in the same manner as other Content Dialogs, such as Merge Tags. Please review the Content Dialog section for more details about how to use Beefree SDK’s Content Dialog feature.
An example Metadata Content Dialog configuration can be found below.
The metadata resolve function now accepts an options
object in which you can pass the property synced
to determine if the row needs to be saved and treated by the builder as synced.
When the Metadata Content Dialog is completed, the application triggers the Saved Rows callback. The callback returns the following details:
rowJSON JSON of the selected row.
rowHTML HTML preview of the selected row
pageJSON Page Partial of the selected row contained in a page (for editing a row as an independent piece of content).
With Edit Single Row mode you can offer an easy way for your end users to edit saved rows individually, using a tailored UI built to modify the row structure, content, and style settings without worrying about messing up with the overall design of the email campaign, landing page, or pop-up.
Enabling a more modular approach to saved rows simplifies how users can design and act on content: updating small details in a saved row, saving it, then deploying it to existing templates becomes a matter of minutes. If you want to learn more about how to leverage Edit Single Row mode to safely modify a Saved Row, take a look at the dedicated technical documentation.
This page discusses the ways that you can manage reusable content within the builder. There are different row management options, such as delete, edit, or display rows, available to you and your application's end users. Throughout this page, we will discuss these options and how you can implement them.
Note: To sync rows, visit the Implement Synced Rows page.
There is no limit to the number of rows passed to the builder in each array of custom rows.
However, the builder UI will only display the first 30 items (i.e., the first 30 rows in the array).
The rest of them will not show until the user performs a search that matches them. If the search matches over 30 items, the first 30 are displayed.
This filtering is applied to prevent performance degradation in the browser.
The search field allows users to narrow down the content shown after they select a list of custom rows.
The search is performed against all elements of the array (i.e., both visible and hidden), and the first 30 items (i.e., the first 30 rows in the array that match the search criteria) are shown.
All textual content included in the selected array – including image file names – is used to find a match.
The order of the JSON nodes in rowsConfiguration
defines the order in which the lists of custom rows will display in the drop-down. It also determines which list of rows will be used as default (selected) when the user clicks on the Rows tab for the first time during the session.
The first ordering factor refers to the type of row (empty, default, custom). That’s defined by how the following parameters are listed in rowsConfiguration:
emptyRows
defaultRows
externalContentURLs
You would list defaultRows
before emptyRows
to obtain the order shown in the following screenshot:
The order inside the externalContentURLs
node defines the order of the Custom rows.
In the above example configuration:
emptyRows
will be the first item in the drop-down and the default selection when clicking on the Rows tab.
defaultRows
will be the second item in the drop-down.
The lists of rows defined in externalContentURLs
will follow their ordering in the drop-down.
It’s up to you – the host application – to decide what’s available and in which order.
Note the following row type requirements when configuring your rowsConfiguration parameter:
emptyRows
and defaultRows
are not required.
This allows you to load just Custom rows through externalContentURLs
, if needed, controlling which rows end users can drag and drop into the builder.
The maxRowsDisplayed
parameter enables you to define the number of rows displayed under each user-created category in the application's sidebar, without affecting the "Empty" and "Default" categories. It directly influences the number of saved rows an end user sees when they click on a category in the sidebar.
You can set the maxRowsDisplayed
parameter in the rowsConfiguration
object in the Beefree SDK Configuration as follows:
The following section discusses how to configure the Saved Rows Management categories.
Accessing, and organizing saved rows is intuitive with Saved Rows Management. With this feature, there is an available action in the list of saved rows that your application can intercept to handle changes in this list itself. This means you can delete, rename, or re-organize your saved rows inside the builder.
Implementing Saved Rows Management Actions requires some development effort from the host application. This section outlines what you need to know for each action.
To get started, you will need to create a content dialog in your application configuration parameters. The content dialog method should be named onDeleteRow
and be nested under the contentDialog
object, as follows:
Following that, amend your rowsConfiguration
object with the additional parameters:
The handle
parameter to utilize in your onDeleteRow
handler from the previous step
The optional behaviors
parameter to set management permissions
Here’s an example:
When the onDeleteRow
method is called, utilize the 3rd parameter to obtain an argument containing the handle value of the row being requested, as well as the row metadata. Use the handle and the row’s metadata to determine which row should be deleted.
Finally, we can call the resolve
method, passing the value true
if you want to refresh the rows, or false
if you want to keep the side panel’s current listing.
To get started, much like with deleting rows, you will need to create a content dialog in your application configuration parameters. The content dialog method should be named onEditRow
and be nested under the contentDialog
object, as follows:
Following that, amend your rowsConfiguration
object with the additional parameters:
The handle
parameter to utilize in your onEditRow
handler from the previous step
The optional behaviors
parameter to set management permissions
Here’s an example:
When the onEditRow
method is called, utilize the 3rd parameter to obtain an argument containing the handle value of the row being requested, as well as the row metadata. Use the handle and the row’s metadata to determine which row should be edited.
Finally, we can call the resolve
method, passing the value true
if you want to refresh the rows, or false
if you want to keep the side panel’s current listing.
Saved Rows Management also provides errors and warnings for your application, so you can handle all cases gracefully.
You can call the reject
method, passing the message you want to display.
This feature is available on Beefree SDK and above. If you're on the Essentials plan, for free to try this and other Core-level features.
Synced Rows expands on the foundational capabilities of and , helping users manage rows more effectively. Using the merge-rows
and synced-rows
methods in the , you can create an efficient row management workflow. This ensures that when users update content in one row marked as “synced,” those updates are reflected across all connected designs using that synced row.
Cross-design synchronization: Sync saved row contents across multiple linked designs.
Design consistency: Lock rows in linked designs to keep designs uniform.
Editing flexibility: Convert rows from synced to unsynced, making individual changes as needed.
Intuitive edit indicator: Look for the pencil icon at the top-right of synced rows, which provides access to editing options
Auto-updating contacts: Change a contact in one email, and it updates across multiple campaigns.
Effortless re-branding: Edit your logo once and watch it reflect across all designs.
Unified transactional footers: Update details like copyright or social links, and it automatically updates in all relevant email templates.
Row details: This includes structure, settings, and styles.
Content details: Settings and styles of individual content blocks.
Metadata: Any metadata tied to the saved row.
Prior to implementing Synced Rows, review the following prerequisites:
When a row is saved with the synced
property, it becomes a “synced row.” To maintain consistency, synced rows cannot be edited within a design. Instead, they function as reference points, ensuring uniformity across all linked designs. The host app must load the row’s JSON using Single Row Edit Mode to edit synced rows. Any modifications to synced rows can be propagated to all linked designs with the help of the CSAPI’s merge-rows
and synced-rows
methods.
Unsynced saved rows, in contrast, allow for edits that don’t impact other designs. They’re ideal for making design-specific changes without influencing other designs that might share the same base row.
As previously mentioned, a synced row is a saved row designated synced
when saved. To set a row’s synced property, adjust the JSON response from the saveRow
Content Dialog.
You might need to modify the saveRow
handler from the Metadata Content Dialog step in your app’s Save Rows workflow.
If you need a refresher, check out:
Here’s a sample implementation for the Metadata Content Dialog, offering the synced row option:
The JSON returned to the builder includes the user’s input and selections from the UI. The configuration below shows the new synced row setting applied to the options argument of the resolve method.
Look for the pencil icon at the top-right of synced rows. Rows without this icon are standard saved rows. The icon provides a clear visual cue for quickly identifying and editing synced rows.
To edit a synced row, click the pencil icon. Editing options appear in the sidebar panel. Inside, you’ll find a CTA button and optional text.
The CTA button opens the editSyncedRow
Content Dialog, allowing the host application to interact with the end-user and receive their selection.
The host application has complete control over the content dialog and UX. However, the content dialog must always return a boolean value of true
or false
to trigger one of the following outcomes:
If true
, the row remains synced to disable content editing in the design before closing the dialog.
If false
, the row updates to enable editing and remove the synced property before closing the dialog.
For example, a content dialog might present users with two options:
Edit the row across all designs.
Unsync the row, turning it into a standard saved row.
The first option, to edit the row across all designs, allows users to make changes to the synced row that will be reflected in all designs that use it.
The second option, to unsync the row, converts the synced row into a standard saved row. This means that any changes made to the row will only affect the design in which it is being edited. This option is useful when the user needs to make specific changes to a single design without affecting other designs that may use the same saved row.
The user’s selection from the above example editSyncedRow
content dialog UI is returned to the builder as a boolean value. Below is an example of the editSyncedRow
configuration for the UI above. Note the boolean value false
in the resolve method unlocks the row:
The following animation shows this example of edit synced rows workflow in action. We’ll dive into this process in the following sections.
Suppose a user selects “Edit and update everywhere” from the content dialog. How does the host app ensure seamless editing and synchronization of the row?
Here’s a breakdown of the typical workflow the host app adopts:
User edits: Users generally hit ‘Save’ to confirm their edits once they modify the synchronized row. Simultaneously, the host app can proactively track these edits using the onChange
method.
Synchronization timing: The decision on when to synchronize changes across all designs rests with the host application. Given the potential need to propagate edits to multiple designs, holding off until the user indicates their wish to exit is customary.
Initiation of synchronization: The synchronization is initiated as soon as the user signifies their satisfaction with the edits, either through the ‘Save’ or ‘Save & Exit’ options.
Background syncing: Given the possible existence of numerous linked designs, a background process is usually set in motion to update all other templates.
In the fifth step of the sample workflow, the goal is to bring the user back to their ongoing design with the updated content. This is achieved using the CSAPI’s merge-rows
method.
The merge-rows
method functions as a sophisticated “find and replace.”
i.e., To synchronize content, the host app forwards a request comprising the outdated template, the newly edited row, and a succinct query detailing which row(s) the API should target for replacement. The “query” is a standards-based JSON Path query typically referencing a globally unique identifier that was added to the saved row during the Metadata Content Dialog step.
To update rows across all designs, keeping track of the templates where rows have been dropped is crucial. There are two principal methods to associate rows with templates:
Using the onChange
method
Upon adding a synced row into a design, the onChange
callback method supplies the row’s metadata. The metadata will contain the row’s guid
, which can be used to link the synced row to the guid
assigned to the template by the host app. Commonly, this is achieved by establishing an index record within the app’s database linking the template’s guid
with the row’s guid
.
Leverage the synced-rows
method
The specific objectives of the host application steer the choice between these methods. Whatever the choice, the primary focus is meticulously tracking the row across all linked templates, ensuring accurate and efficient updates.
This feature is available on Beefree SDK and above.
Hosted Saved Rows simplifies row management by allowing you to store and retrieve saved rows using Beefree SDK's secure infrastructure. This fully managed solution eliminates the need for custom backend systems and UI development, enabling faster implementation and reduced maintenance.
This guide explains how to enable Hosted Saved Rows and configure advanced permissions to control row access and management.
To enable Hosted Saved Rows for your application, follow these steps:
Log in to the .
Navigate to the application you'd like to configure Hosted Saved Rows for.
Click on Details.
Navigate to Application configuration and click View more.
Scroll to the Saved Rows section.
Toggle on the Hosted on the Beefree SDK Infrastructure option.
Read the pricing information in the popup closely, because additional fees may apply.*
If you'd like to proceed, confirm you read and understand the pricing to activate the feature.
Important: Keep in mind that charges apply for saved rows that are hosted not only in your production applications, but also for your development applications.
*Hosted Saved Rows have the following pricing structure:
Rows saved by your application's end users will be stored and hosted in the Beefree SDK storage option.
End users can save rows directly to the hosted infrastructure and retrieve them as needed.
canDeleteHostedRow
: Allows or prevents deleting hosted rows.
canEditHostedRow
: Enables or disables editing of hosted rows.
canManageHostedRowCategory
: Controls whether end users can manage row categories.
canAddHostedRowCategory
: Determines if end users can add new categories.
If both canDeleteHostedRow
and canEditHostedRow
are set to false
, the row menu will be hidden.
If both canManageHostedRowCategory
and canAddHostedRowCategory
are set to false
, the category management menu will be hidden.
The following configuration displays an example of the rows
object inside of advancedPermissions
:
Once Hosted Saved Rows is activated, end users can:
Save rows directly from the builder using the Save icon.
Name and categorize rows into categories for better discoverability.
Access, reuse, edit and delete rows through the Rows tab in the side panel.
: Implement first, because it establishes the foundation for a row management workflow.
& : Familiarizing yourself with Edit Single Rows Mode and CSAPI will provide you with a mechanism to edit and manage synced rows, which will support your implementation workflow. However, they are not strictly necessary to implement Synced Rows.
A comprehensive reference of the editSyncedRow
Content Dialog settings, such as the CTA button label and optional text, can be found in our .
Initialization: The host app launches the Edit Single Row Mode in a new builder instance to enable editing of the synchronized row. Our is available for reference for a deeper understanding.
Redirection & Synchronizing changes: After editing a row, the host app usually performs a synchronous . The user will then be redirected to their ongoing design, where they can see their edits reflected in the synced row.
For an example on how to use the merge-rows
method, visit our .
For those rows incorporated into designs before the implementation of the onChange
tracking method, CSAPI’s synced-rows
method is available. Use the synced-rows
method get a list of all the synced rows inside a template with their corresponding rowIdentifier
values. To learn more about how to use this endpoint, visit our.
Note: Visit our to learn more about Hosted Saved Rows pricing.
Once you've successfully enabled Hosted Saved Rows in the , you'll access the following:
Hosted Saved Rows includes to control how rows and categories are accessed and managed. These permissions allow you to define user capabilities, such as editing or deleting rows.
Visit the to learn more about the following topics:
Allotment
Not available
Not available
100 Hosted Rows
250 Hosted Rows
1000 Hosted Rows
Price for extra unit
$0.35/Hosted Rows
$0.25/Hosted Row
$0.20/Hosted Row
This feature is available on Beefree SDK Core plan and above. If you're on the Essentials plan, upgrade a development application for free to try this and other Core-level features.
The Reusable Content page discusses, on a very high-level, the differences between key row-related features offered within Beefree SDK. This page provides more detailed information on pre-building and saving reusable content.
By enabling the Save Rows feature, your end users will be able to save design elements that they want to use in other designs in the future.
To display saved rows in the Rows tab, add them to the list of rows available to users by leveraging the Custom Rows feature.
When using the standard, empty rows, users are forced to start from scratch every time they introduce a new row.
A set of pre-built rows may accelerate message construction, providing users with commonly used structures filled with sample content. For example, a set of headers, footers, news sections, etc.
With Custom rows you – the host application – are in control of the content that is included. In some cases, providing canned text can speed up the email creation process and provide consistency across all the communications.
Imagine, for example, the case of a CRM where customer success representatives can quickly build curated emails selecting from a number of pre-built text blocks.
In addition to the empty rows that have always been part of the Beefree SDK system, we now provide a set of default rows that you can add to your application with a simple configuration parameter.
They feature a series of popular structures, filled with placeholder text, images, and buttons.
For some users, they may work better than empty rows as they allow them to immediately visualize what they can accomplish with a specific structure.
Reference Rows Configuration to learn more about how to configure these sample rows.
Does your application onboard users asking for company or brand information?
If so, you can use custom rows to provide footers with legal information already applied (and centralized), header designs that already include the company logo, etc.
Other common use cases:
Approved promotional material
QR codes or barcodes
Advertising content
Product recommendation templates
Check how to configure these sample rows below under Rows configuration > Parameters > Default rows
Create custom rows with content from different sources like blogging platforms, content management systems, etc.
This will allow your customers to save time and reduce errors by avoiding copying and pasting text, links, and images.
Additionally, this helps you ensure that only reviewed and approved contents, provided by a common repository, are used in the message creation.
Transform products from your e-commerce catalog into custom rows, using product images, text, and call to actions to create a promotional message with a few clicks.
You can divide the products into categories and feed them into the builder as different arrays of custom rows.
Or you can use different sets of custom rows to provide different layout options in order to add design flexibility.
Saved Rows allows users to select a row in a message and save it for later use. More specifically, it allows users to submit a request to the host application to save a piece of content and turn it into a reusable element. The host application, using the Custom Rows feature, can feed these saved elements back to the builder as rows that can be dragged into other messages.
In this tutorial, you will learn how to implement Saved Rows in an application that has embedded Beefree SDK.
Also, see the sample code!
When the feature is enabled, a new Save icon is added to the action icons when a row is selected:
The same action is also available in the row properties panel when a row is selected:
By clicking on this icon, users trigger a request to the host application to store the row’s JSON document, which includes:
row structure and settings;
contents and their settings;
all style settings.
It is entirely up to the host application:
where to store the JSON documents that describe these saved rows;
if and how to display them to users of the application;
whether to allow users to edit them individually
when and how to feed them back to the builder, using the Custom Rows feature.
There are two schemas that are important to understand and utilize when working with both Custom Rows and Self-hosted Saved Rows.
These schemas are the following:
Throughout the subsequent pages, these two schemas and their applications will be referenced and discussed more thoroughly.
The following code snippet provides an example of the Simplified Rows Schema.
The following is the basic structure of the row’s JSON schema. Simply put, the schema is the structure of your saved rows data feed.
NOTE: The row schema is complex and we do not recommend creating rows programmatically. Therefore, there is no schema reference of the row itself. However, you can add your own parameters to the row’s metadata or use our Simplified Row Schema to generate them programmatically from existing content.
The metadata section of the rows schema allows you to keep track of row-specific information.
name The saved row’s title displayed in the Rows panel.
A string of plain text that identifies the row.
Displayed in the row card when the row is shown in the Rows panel.
Used for text searches within the Rows panel
Recommended metadata
category A category can be useful for organizing your feeds on the Rows tab.
id A handle that identifies the row in the host application’s data storage.
idParent Useful to track rows that were saved from previously saved rows. Keeping track of where a row came from allows you to implement additional editing features.
dateCreated The date the row was created: useful for filtering/sorting rows for content management purposes in your application. It can also help with technical support tasks.
dateModified The date a saved row was updated: useful for filtering/sorting rows for content management purposes in your application. It can also help with technical support tasks.
userId To let your application decide whom can edit or saved rows.
tags Useful to create filters, management, search, and in general to organize the content in your application.