Skip to main content

Brizy Config

Brizy config is the configuration our builder starts with. The config can influence the starter page, global styles, menu, dynamic content etc.
This config is needed to be able to load the editor in 3 modes: page, popup, story

Page

To load page, use: config.mode = "page"



Popup

To load popup, use: config.mode = "popup"



Story

To load story, use: config.mode = "story"



The full config can be seen below:

type config = {
container: HTMLElement;
pageData: Record<string, unknown>;
projectData: Record<string, unknown>;

// html: Array of strings with Styles & Scripts
// json: Array of more granular objects, used when needing to merge multiple pages into one
// Use this case when you need to create a fully customizable preview HTML
htmlOutputType: "html" | "json";

// Page: Static Page view
// Popup: Static Popup view with conditions(open on exit, open after x minutes)
// Story: Static story carosuel view
mode: "page" | "popup" | "story";

// Menu
menu?: Array<Menu>;

// Integration
integration?: {
/// Form
form?: {
action?: string;
recaptcha?: {
siteKey: string;
};
fields?: {
label?: string;
handler: (res: Response<Array<FormFieldsOption>>, rej: Response<string>) => void;
};
};
};

// L10n
l10n?: Record<string, string>;

// Extensions
extensions?: Array<Extension>;

// DynamicContent
dynamicContent?: {
groups?: {
[DCTypes.image]: Array<ConfigDCItem> | DCItemHandler;
[DCTypes.link]: Array<ConfigDCItem> | DCItemHandler;
[DCTypes.richText]: Array<ConfigDCItem> | DCItemHandler;
};
};

pagePreview: string;

// UI
ui: {
popupSettings?: {
displayCondition?: boolean;
deletePopup?: boolean;
embedded?: boolean;
horizontalAlign?: boolean;
verticalAlign?: boolean;
backgroundPreviewUrl?: string;
scrollPageBehind?: boolean;
clickOutsideToClose?: boolean;
};

theme?: Theme;

leftSidebar?: {
topTabsOrder?: Array<"cms", "addElements", "reorderBlock", "globalStyle", "deviceMode", "more">;
bottomTabsOrder?: Array<"cms", "addElements", "reorderBlock", "globalStyle", "deviceMode", "more">;

more?: {
options?: Array<{
type: "link";
label: string;
link: string;
linkTarget?: "_blank" | "_self" | "_parent" | "_top";
}>;
};

cms?: {
onOpen: (onClose: VoidFunction) => void;
onClose?: VoidFunction;
};

// AddElements
moduleGroups?: Array<{
label: string;
moduleNames: Array<BaseElementTypes | StoryElementTypes>;
}>;
};
};

// API
api?: {
/// Media
media?: {
mediaResizeUrl?: string;
imagePatterns?: ImagePatterns;

addMedia?: {
handler: (resolve: Response<AddMediaData>, reject: Response<string>, extra: AddMediaExtra) => void;
};
};

// File
customFile?: {
fileUrl?: string;

addFile?: {
handler: (res: Response<AddFileData>, rej: Response<string>, extra: AddFileExtra) => void;
};
};

// Default Blocks | Kits | Popups | Stories
// More information about defaultKits, defaultPopups, defaultLayouts and defaultStories types you can find here: https://github.com/EasyBrizy/Brizy-Local-Editor/blob/master/packages/core/src/types/types.ts
defaultKits?: DefaultKits;
defaultPopups?: DefaultPopups;
defaultLayouts?: DefaultLayouts;

// Used only in mode: story
defaultStories?: DefaultStories;

// Screebnshots
screenshots?: {
screenshotUrl?: string;
create?: (res: Response<{ id: string }>, rej: Response<string>, extra: ScreenshotData) => void;
update?: (res: Response<{ id: string }>, rej: Response<string>, extra: ScreenshotData & { id: string }) => void;
};
};

onSave?: (data: Output) => void;
onAutoSave?: (data: AutoSave) => void;
autoSaveInterval?: number;
onLoad?: VoidFunction;
};

interface AutoSave {
pageData?: Record<string, unknown>;
projectData?: Record<string, unknown>;
}

interface Output {
pageData: {
[k: string]: unknown;
compiled?: {
html: string;
scripts: Array<string>;
styles: Array<string>;
};
};
projectData: {
[k: string]: unknown;
compiled?: {
styles: Array<string>;
};
};

// Only in popup mode
popupSettings?: {
verticalAlign: "top" | "bottom" | "center";
horizontalAlign: "left" | "right" | "center";
};

// Error when html will be undefined
error?: string;
}

// Menu
interface Menu {
id: string;
name: string;
items: Array<MenuItem>;
}

// MenuItem
export interface MenuItem {
type: "MenuItem";
value: {
id: string;
title: string;
url: string;
target?: string;
classes?: Array<string>;

// Dropdown
items?: Array<MenuItem>;
};
}

// FormFieldsOption
export interface FormFieldsOption {
title: string;
value: string;
}

// DynamicContent
export enum DCTypes {
image = "image",
link = "link",
richText = "richText",
}

interface BaseDCItem {
label: string;
placeholder: string;
}

export interface ConfigDCItem extends BaseDCItem {
optgroup?: ConfigDCItem[];
}

interface DCItemHandler {
handler: (
res: Response<BaseDCItem>,
rej: Response<string>,
extra?: { keyCode?: string; placeholder: string; label: string },
) => void;
}

// Media
export interface ImagePatterns {
original: string;
split: string;
full: string;
}
export interface AddMediaData {
uid: string;
fileName?: string; // fileName need contain .ext
}

export interface AddMediaExtra {
acceptedExtensions: Array<string>; // [.jpg, .png, .svg, .etc]
}

// File
export interface AddFileData {
filename: string;
}

export interface AddFileExtra {
acceptedExtensions: Array<string>; // [.jpg, .png, .svg, .zip .txs .etc]
}

// ElementTypes
/// Base Elements used in Page | Popup, these elements doesn't work in Story
export enum BaseElementTypes {
Text = "Text",
Image = "Image",
Button = "Button",
Icon = "Icon",
Spacer = "Spacer",
Map = "Map",
Form2 = "Form2",
Line = "Line",
Menu = "Menu",
ImageGallery = "ImageGallery",
Video = "Video",
Audio = "Audio",
VideoPlaylist = "VideoPlaylist",
IconText = "IconText",
Lottie = "Lottie",
Embed = "Embed",
StarRating = "StarRating",
Alert = "Alert",
Counter = "Counter",
Countdown2 = "Countdown2",
ProgressBar = "ProgressBar",
Calendly = "Calendly",
Carousel = "Carousel",
Tabs = "Tabs",
Accordion = "Accordion",
Switcher = "Switcher",
Table = "Table",
Timeline = "Timeline",
Facebook = "Facebook",
Twitter = "Twitter",
FacebookComments = "FacebookComments",
Columns = "Columns",
Row = "Row",
}

/// Story Elements used only in Story mode, these elements doesn't work in Page, Popup
export enum StoryElementTypes {
StoryButton = "StoryButton",
StoryIcon = "StoryIcon",
StoryEmbed = "StoryEmbed",
StoryText = "StoryText",
StoryMap = "StoryMap",
StoryProgressBar = "StoryProgressBar",
StoryLine = "StoryLine",
StoryCountdown2 = "StoryCountdown2",
StoryCounter = "StoryCounter",
StoryShape = "StoryShape",
StoryForm2 = "StoryForm2",
StoryStarRating = "StoryStarRating",
StoryLottie = "StoryLottie",
StoryImage = "StoryImage",
StoryVideo = "StoryVideo",
}

// Theme
export interface Theme {
colors: {
"--primary-dark"?: string;
"--secondary-dark"?: string;
"--tertiary-dark"?: string;
"--primary-white"?: string;
"--secondary-white"?: string;
"--tertiary-white"?: string;
"--primary-gray"?: string;
"--secondary-gray"?: string;
"--tertiary-gray"?: string;
"--active-color"?: string;
"--light-gray"?: string;
};
}

// Screenshots
export interface ScreenshotData {
base64: string;
blockType: "normal" | "global" | "saved" | "layout";
}

// Extenstions
export interface Extension {
host?: string;
path: string;
}

About config

To be able to start the builder you need to send valid values in the config in the following required keys:

  • container - the HTMLElement in which the builder will be loaded
  • pageData - the JSON with current page structure
  • projectData - the JSON that specifies global styles
  • htmlOutputType - can be "json" | "html" and specifies output type after page update
  • mode - the builder load mode: "page" | "popup" | "story"
  • pagePreview - link of the preview which will be set on "preview" button in UI of the builder
  • ui - the object that let us to customize the left sidebar order, links or elements, also let us to customize popup settings and also the color variables of builder UI

The other keys like menu, integration, l10n etc. are not required and builder can work without them.

Explanation


Config can be passed as an object when you initialize the editor from the script.

First level parameters

NameTypeDescription
containerHTMLElementBrizy Plugin will load into HTML element.
mode"page" | "popup" | "story"Default "page"
htmlOutputType"json"| "html"Default "html"
pageDataobjectLoads the JSON page specified in the pageData parameter.
projectDataobjectLoads the JSON project specified in the projectData parameter.
menuarrayLoad the array of menu
extensionarrayLoad the array of extension scripts and styles
l10nobjectA data structure that maps keys to localized strings for localization purposes. All keys available here
pagePreviewstringLink of the preview which will be set on "preview" button in UI of the builder

Integration parameters

NameTypeDescription
integration.form.actionstringReplace the URL with your own. This is the link where we send the information from the contact form element when the end user submits the form.
integration.form.recaptcha.siteKeystringReCaptcha Site Key
integration.form.fields.labelstringDefines the text displayed in the editor UI.
integration.form.fields.handlerfunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor. In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.

DynamicContent parameters

Builder wrapped all outside placeholder inside builder placeholder {{ placeholder content='Base64(SOME EXTERNAL PLACEHOLDER)' }}

Builder added extra attributes for placeholder

  • Featured Image added cW(Container Width) cH(Container Height) if external service want to crop the image

Example: {{ placeholder content='Base64( {{ featured_image }} )' cW='200' cH='200' }}

  • Extra Context if dynamicContent.groups is an Array

Example: {{ placeholder content='Base64( {{ post_title }} )' entityType='pages' entityId='page1' }}

Dynamic content can be configured in 2 ways

  1. Send an array of placeholder in config via:

DynamicContent array of choices

NameTypeDescription
dynamicContent.groups[DCTypes.image]arrayTakes array of ConfigDCItem for all Element what persis ImageUpload
dynamicContent.groups[DCTypes.link]arrayTakes array of ConfigDCItem for all Element what persis Link
dynamicContent.groups[DCTypes.richText]arrayTakes array of ConfigDCItem for all Element what persis Content html
  1. Send a handler function that sends the placeholder over the response function

DynamicContent option parameters

NameTypeDescription
dynamicContent.groups[DCTypes.image].handlerfunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve({ label:"My_Placeholder", placeholder:"{{ my_placeholder }}" }) ). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
dynamicContent.groups[DCTypes.link].handlerfunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve({ label:"My_Placeholder", placeholder:"{{ my_placeholder }}" }) ). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
dynamicContent.groups[DCTypes.richText].handlerfunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve({ label:"My_Placeholder", placeholder:"{{ my_placeholder }}" }) ). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.

UI parameters

NameTypeDescription
ui.popupSettings.displayConditionbooleanTakes true or false values and lets you turn on or off the global display conditions option together with the display conditions popup.
ui.popupSettings.deletePopupbooleanTakes true or false values and lets you turn on or off the delete popup option. Turn off the delete option when you want to load your json templates in the pageDate parameter. Turning off the delete option will also remove the posibility to access the premade Brizy templates inside the editor.
ui.popupSettings.embeddedbooleanTakes true of false values and lets you turn on or off Vertical align, Horizontal align, Scroll Page Behind and Close Button.
ui.popupSettings.verticalAlignbooleanTakes true or false values and lets you turn on or off the Vertical align.
ui.popupSettings.horizontalAlignbooleanTakes true or false values and lets you turn on or off the Horizontal align.
ui.popupSettings.scrollPageBehindbooleanTakes true or false values and lets you turn on or off the Scroll Page Behind.
ui.popupSettings.clickOutsideToClosebooleanTakes true or false values and lets you turn on or off the Click Outside To Close.
ui.popupSettings.backgroundPreviewUrlstringLets you control the preview background url
ui.leftSidebar.topTabsOrderArrayLets you control the order and turning on or off the icons in the left sidebar at the top. Can take the values: "addElements", "reorderBlock", "globalStyle", "deviceMode" and "more". Leave "blank" if you want to disable one of the icons.
ui.leftSidebar.bottomTabsOrderArrayLets you control the order and turning on or off the icons in the left sidebar at the bottom. Can take the values: "addElements", "reorderBlock", "globalStyle", "deviceMode" and "more". Leave "blank" if you want to disable one of the icons.
ui.leftSidebar.more.optionsArrayLets you add more links in the More dropdown in the left sidebar.
ui.leftSidebar.moduleGroupsArrayLets you control the elements and turing on or off the icons in the addElements in the left sidebar. The default arrangement you can see here
ui.leftSidebar.cms.onOpenfunctionIs a function for Opening External Modals with onClose Callback for CMS Icon Deactivation you can see here.
ui.leftSidebar.cms.onClosefunctionIs a function for Closing External Modals
ui.theme.colorsobjectWe can customize the color variables in builder's UI

API parameters

NameTypeDescription
api.media.mediaResizeUrlstringThis is the URL for the image resizer service. There are two image resizer service options: hosted by Brizy and self hosted. If you choose to use the image resizer service hosted by Brizy, you don't have to change the media.brizylocal.com URL. For the self hosted version you need to replace the media.brizylocal.com with the URL of your image resizer service. Setup your own image resizer service like this
api.media.imagePatternsobjectThis is an object with full, original, and split keys. It's used to control the final URLs for all builder resize and crop operations.
api.media.addMedia.handlerfunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor. In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
api.customFile.fileUrlstringThis is the URL for your resources the final URL will be api.customFile.fileUrl/${fileName}
api.customFile.addFile.handlerfunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor. In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
api.defaultKits.labelstringDefines the text displayed in the editor UI.
api.defaultKits.getKitsfunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve([ Array of kits ])). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
api.defaultKits.getMetafunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve([ Array of kits with blocks ])). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
api.defaultKits.getDatafunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve(block.json)). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
api.defaultPopups.labelstringDefines the text displayed in the editor UI.
api.defaultPopups.getMetafunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve({ blocks: [ Array of blocks with screenshots and id] })). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
api.defaultPopups.getDatafunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve(popup.json)). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
api.defaultLayouts.labelstringDefines the text displayed in the editor UI.
api.defaultLayouts.getMetafunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve({ templates: [ Array of layouts with pages and every page must have screenshots and id] })). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
api.defaultLayouts.getDatafunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve([ page.json ])). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
api.defaultStories.labelstringDefines the text displayed in the editor UI.
api.defaultStories.getMetafunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve({ stories: [ Array of stories, every story must have screenshots and id] })). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
api.defaultStories.getDatafunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve([ story.json ])). In case you want to cancel the operation, call the reject() function. A resolve or reject call is mandatory. If you miss this step, the editor will remain in waiting mode. Error management on the host application must call the reject function to unblock the editor.
api.screenshots.screenshotUrlstringThis is the URL for the Screenshot
api.screenshots.createfunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve({ id: screenshot id })). In case you want to cancel the operation, call the reject() function.
api.screenshots.updatefunctionIs a function with a Promise-like signature. This function lets you use your own logic to retrieve the desired value. Once the value is available, you must call the resolve(value) function to pass it to the editor ( example of resolve: resolve({ id: screenshot id })). In case you want to cancel the operation, call the reject() function.
api.onSaveJSONFired when the Save button is clicked
api.onAutoSaveJSONFired after Auto Save happened in editor
api.onLoadJSONFired when the builder is loaded
api.autoSaveIntervalnumberDefault 2000. Set a ms delay for onAutoSave function

Examples


Example Media Handler

const config = {
api: {
media: {
handler(resolve, reject, extra) {
// extra: { acceptedExtensions: Array<string> }
resolve({
uid: "1234",
fileName: "picture.png",
});
},
},
},
};

Example Media Handler with Brizy Image Resizer & AWS S3

The builder uses two keys: uid and fileName, or only uid (with file extensions). The main idea is to resolve problems with the duplication of images. If the duplication was resolved by some media upload gallery, then send only fileName to uid. For example: resolve({uid: "picture.png"}).

Image Patterns

Used to specify where the crop params from the builder need to be included in the URL. The imagePatterns object contains 3 keys: full, original, split. The value of every key must be send the placeholders The placeholder has syntax: {{ oY=[oY] }}

Support placeholders:

  • [baseUrl]: the base URL sent via api.media.mediaResizeUrl
  • [iW]: the original image width (number or any)
  • [iH]: the original image height (number or any)
  • [oX]: the pointer X (number)
  • [oY]: the pointer Y (number)
  • [cW]: the container width, used to crop image (number)
  • [cH]: the container height, used to crop image (number)
  • [uid]: the UID of the image
  • [fileName]: optional placeholder; it would be used if resolve({uid: "1234", fileName: "picture.png"})

Example:

const config = {
api: {
media: {
mediaResizeUrl: "http://localhost:7788/media", // HOST
imagePatterns: {
full: "{{ [baseUrl] }}/{{ iW=[iW] }}&{{ iH=[iH] }}&{{ oX=[oX] }}&{{ oY=[oY] }}&{{ cW=[cW] }}&{{ cH=[cH] }}/{{ [uid] }}/{{ [fileName] }}",
original: "{{ [baseUrl] }}/{{ [sizeType] }}/{{ [uid] }}/{{ [fileName] }}",
split: "{{ [baseUrl] }}/{{ iW=[iW] }}&{{ iH=[iH] }}/{{ [uid] }}/{{ [fileName] }}",
},
},
},
};

Full:

<img src="http://localhost:7788/media/iW=1808&iH=1017&oX=448&oY=53&cW=515&cH=605/1234/picture.jpg" />

Original:

<img src="http://localhost:7788/media/original/1234/picture.jpg" />

Split:

<img src="http://localhost:7788/media/iW=5000&iH=any/1234/picture.jpg" />

ImageKit example:

const config = {
api: {
media: {
mediaResizeUrl: "https://ik.imagekit.io/demo", // ImageKit HOST
imagePatterns: {
full: "{{ [baseUrl] }}/tr:{{ w-[cW] }},{{ h-[cH] }},c-maintain-ratio/{{ [fileName] }}",
split: "{{ [baseUrl] }}/tr:{{ w-[iW] }},c-at_max/{{ [fileName] }}",
original: "{{ [baseUrl] }}/tr:orig-true/{{ [fileName] }}",
},
},
},
};

Full: Used inside the Image element where cropping or resizing of the image is needed. Original: Used when the builder tries to access the original URL of the image, for example, as a background for Section, Column, or Row. Split: Used when the builder tries to access the resized URL for the image, for example, as a background.

This case(split) is usually used when the client uploads very large images (e.g., 10MB), and we need to resize them to a smaller size (e.g., 1MB). In this case iH=any

// In HTML
// <script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.24.min.js"></script>

const bucketName = "AWS_BUCKET_NAME";
const bucketRegion = "AWS_REGION";
const identityPoolId = "AWS_IDENTITY_POOL_ID";
const AWS = window.AWS;

// More details about AWS you can see here https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html
AWS.config.update({
region: bucketRegion,
credentials: new AWS.CognitoIdentityCredentials({
IdentityPoolId: identityPoolId,
}),
});
const s3 = new AWS.S3({
params: {
Bucket: bucketName,
},
});

const config = {
api: {
media: {
// You need to start a Brizy Image Resize
/// for more information on how you can do that see here https://github.com/EasyBrizy/Brizy-Local-Image-Resizer#readme
/// ORIGIN_MEDIA_URL=https://${AWS_BUKET_NAME}/media
mediaResizeUrl: "http://localhost:7788/media", // HOST [Brizy Image Resizer]
handler(resolve, reject, extra) {
const input = document.createElement("input");
input.type = "file";
input.accept = "image/*";

input.addEventListener("change", function (e) {
const { files } = e.target;

if (files && files.length) {
const file = files[0];
const fileName = file.name;
const uid = crypto.randomUUID();
const filePath = `media/${uid}/${fileName}`;
const s3Config = {
Key: filePath,
Body: file,
};

// Upload to S3
s3.upload(s3Config, (err) => {
if (err) {
reject(`Wrong Upload to S3 ${err.message}`);
} else {
resolve({ uid, fileName });
}
});
}
});

// Open Upload Window
input.click();
},
},
},
};

Default ModulesGroup

// Popup
const defaultConfigModulesGroupForPopup = {
ui: {
leftSidebar: {
moduleGroups: [
{
label: "grid",
moduleNames: ["Columns", "Row"],
},
{
label: "essentials",
moduleNames: ["Text", "Image", "Button", "Icon", "Spacer", "Map", "Form2", "Line"],
},
{
label: "media",
moduleNames: ["ImageGallery", "Video", "Audio", "VideoPlaylist"],
},
{
label: "content",
moduleNames: [
"IconText",
"Embed",
"StarRating",
"Alert",
"Counter",
"Countdown2",
"ProgressBar",
"Calendly",
"Carousel",
"Tabs",
"Accordion",
"Switcher",
"Table",
"Timeline",
],
},
{
label: "social",
moduleNames: ["Facebook", "Twitter", "FacebookComments"],
},
],
},
},
};

// Story
const defaultConfigModulesGroupForStory = {
ui: {
leftSidebar: {
moduleGroups: [
{
label: "essentials",
moduleNames: [
"StoryButton",
"StoryIcon",
"StoryEmbed",
"StoryText",
"StoryMap",
"StoryProgressBar",
"StoryLine",
"StoryCountdown2",
"StoryCounter",
"StoryShape",
"StoryForm2",
"StoryStarRating",
"StoryLottie",
],
},
{
label: "media",
moduleNames: ["StoryImage", "StoryVideo"],
},
],
},
},
};

// Page
const defaultConfigModulesGroupForPages = {
ui: {
leftSidebar: {
moduleGroups: [
{
label: "grid",
moduleNames: ["Columns", "Row"],
},
{
label: "essentials",
moduleNames: ["Text", "Image", "Button", "Icon", "Spacer", "Map", "Form2", "Line", "Menu"],
},
{
label: "media",
moduleNames: ["ImageGallery", "Video", "Audio", "VideoPlaylist"],
},
{
label: "content",
moduleNames: [
"IconText",
"Embed",
"StarRating",
"Alert",
"Counter",
"Countdown2",
"ProgressBar",
"Calendly",
"Carousel",
"Tabs",
"Accordion",
"Switcher",
"Table",
"Timeline",
],
},
{
label: "social",
moduleNames: ["Facebook", "Twitter", "FacebookComments"],
},
],
},
},
};

Example API Default Kits

export type KitItem = {
id: string;
title: string;
};

const config = {
api: {
defaultKits: {
async getKits(res, rej) {
try {
const kits = await fetch("https://example.com/kits").then((r) => r.json());

res([
{
id: "kit001",
title: "Kit #1",
},
{
id: "kit002",
title: "Kit #2",
},
]);
} catch (e) {
rej("Failed to load Kits");
}
},
async getMeta(res, rej, kit) {
try {
const meta = await fetch(`https://example.com/kits/${id}`).then((r) => r.json());
res({
blocks: [
{
id: "Kit2Starter",
cat: [0],
title: "Kit2Starter0Dark",
type: 1,
keywords: "start",
thumbnailHeight: 311,
thumbnailWidth: 600,
thumbnailSrc: "https://example.com/kits/images/thumb_1.jpg",
pro: false,
kitId: "kit001",
blank: "blank",
},
{
id: "block2kit9081",
cat: [2, 16],
title: "block2kit9081",
type: 1,
keywords: "forms,hero,image",
thumbnailHeight: 327,
thumbnailWidth: 600,
thumbnailSrc: "https://example.com/kits/images/thumb_2.jpg",
pro: false,
kitId: "kit001",
},
],
categories: [
{
id: 0,
slug: "blank",
title: "Blank",
hidden: true,
},
{
id: 16,
slug: "hero",
title: "Hero",
},
],
id: "kit001",
name: "Kit #2",
styles: [
{
id: "style042",
title: "Overpass",
colorPalette: [
{
id: "color1",
hex: "#A170D9",
},
{
id: "color2",
hex: "#1C1C1C",
},
],
fontStyles: [
{
id: "paragraph",
title: "Paragraph",
fontFamily: "overpass",
fontFamilyType: "google",
fontSize: 16,
fontSizeSuffix: "px",
fontWeight: 400,
lineHeight: 1.9,
},
],
},
],
types: [
{
id: 1,
name: "dark",
title: "Dark",
icon: "nc-dark",
},
],
});
} catch (e) {
rej("Failed to get json");
}
},
async getData(res, rej, kit) {
try {
const data = await fetch(`https://example.com/blocks/${kit.id}.json`).then((r) => r.json());
res(data);
} catch (e) {
rej("Failed to load resolves for selected DefaultKits");
}
},
},
},
};

Example API Default Popups

const config = {
api: {
defaultPopups: {
async getMeta(res, rej) {
try {
const popups = await fetch("https://example.com/popups").then((r) => r.json());

res({
blocks: [
{
id: "popup2000",
thumbnailWidth: 600,
thumbnailHeight: 417,
title: "popup2000",
keywords: "",
cat: [1493],
type: 0,
pro: true,
thumbnailSrc: "https://example.com/popups/images/thumb_1.jpg",
},
{
id: "popup1773",
thumbnailWidth: 600,
thumbnailHeight: 364,
title: "popup1773",
keywords: "",
cat: [1579],
type: 0,
pro: true,
thumbnailSrc: "https://example.com/popups/images/thumb_2.jpg",
},
],
categories: [
{
id: 1579,
slug: "features",
title: "Features",
},
{
id: 1493,
slug: "sale",
title: "Sale",
},
],
});
} catch (e) {
rej("Failed to get json");
}
},
async getData(res, rej, kit) {
try {
const data = await fetch(`https://example.com/popups/${kit.id}.json`).then((r) => r.json());
res(data);
} catch (e) {
rej("Failed to load resolves for selected DefaultPopups");
}
},
},
},
};

Example API Default Layouts

const config = {
api: {
defaultLayouts: {
async getMeta(res, rej) {
try {
const meta = await fetch("https://example.com/layouts").then((r) => r.json());

const page = {
id: "page1",
thumbnailWidth: 680,
thumbnailHeight: 1282,
thumbnailSrc: "https://example/com/page1/picture.png",
title: "Homepage",
keywords: "home, details, menu, reservation, food, lunch",
cat: [100],
};
const layout = {
name: "Template Name",
color: "#FF7102",
cat: [100],
pages: [page],
styles: [], // Global Style JSON
};
const data = {
templates: [layout],
categories: [
{
id: 100,
title: "Business",
},
{
id: 200,
title: "Travel",
},
],
};

res(data);
} catch (e) {
rej("Failed to get json");
}
},
async getData(res, rej, id) {
try {
const data = await fetch(`https://example.com/layouts/${id}.json`).then((r) => r.json());
res(data);
} catch (e) {
rej("Failed to load resolves for selected DefaultLayouts");
}
},
},
},
};

Example API Default Stories

const config = {
api: {
defaultStories: {
async getMeta(res, rej) {
try {
const meta = await fetch("https://example.com/stories").then((r) => r.json());
const page = {
id: "story1",
thumbnailWidth: 680,
thumbnailHeight: 1282,
thumbnailSrc: "https://example/com/story1/picture.png",
title: "Homepage",
keywords: "home, details, menu, reservation, food, lunch",
cat: [100],
};
const story = {
name: "Story Name",
color: "#FF7102",
cat: [100],
pages: [page],
styles: [], // Global Style JSON
};
const data = {
stories: [story],
categories: [
{
id: 100,
title: "Business",
},
{
id: 200,
title: "Travel",
},
],
};

res(data);
} catch (e) {
rej("Failed to get json");
}
},
async getData(res, rej, id) {
try {
const data = await fetch(`https://example.com/story/${id}.json`).then((r) => r.json());
res(data);
} catch (e) {
rej("Failed to load resolves for selected DefaultStories");
}
},
},
},
};

Example API Screenshots

export interface ScreenshotData {
base64: string;
blockType: "normal" | "global" | "saved" | "layout";
}

const config = {
api: {
screenshots: {
screenshotUrl: "https://example.com/screenshots",
async create(res, rej, data: ScreenshotData) {
try {
const screenshot = await fetch("https://example.com/api/screenshot", {
method: "POST",
body: JSON.stringify({ image: data.base64 }),
}).then((r) => r.json());

res({ id: screenshot.id });
} catch (e) {
rej("Failed create the screenshot");
}
},
async update(res, rej, data: ScreenshotData & { id: string }) {
try {
const data = await fetch(`https://example.com/api/screenshot/${data.id}`, {
method: "PUT",
body: JSON.stringify({ image: data.base64 }),
}).then((r) => r.json());

res(data);
} catch (e) {
rej("Failed to update screenshot");
}
},
},
},
};