> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt ## Resource: About Custom Elements in Blocks ## Article: Custom Elements in Blocks ## Article Link: https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/code-in-blocks/about-custom-elements-in-blocks.md ## Article Content: # About Custom Elements in Blocks
**Editor compatibility** Wix Blocks apps aren't supported in the Wix Harmony editor. Existing Blocks apps remain available for purchase on the Wix App Market for Wix Editor and Wix Studio sites. To learn more, see [About Wix Harmony and Blocks](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/about-wix-harmony-and-blocks.md).Enhance your Blocks widgets with your own design features and CSS capabilities, use any web technology or third party libraries, with Custom Elements. You can add any Javascript component by linking a custom element to a server URL or a Velo file. If needed, you can set more attributes directly from Blocks.
**Important:** Custom elements in the editor are sandboxed for security, restricting access to web storage and caching APIs like cookies, local storage, and IndexedDB. To learn more, see [About Site Widgets](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/site-extensions/site-widgets/about-site-widget-extensions.md#sandboxing-in-the-editor).
**Example:** To see an example of a custom element in Blocks, go to the [Pie Chart](https://dev.wix.com/apps-templates/template?id=9a55382c-c755-4f01-bda2-80b85630acdd&http_referrer=documentation&http_referrer=documentation) app template.## What Are Custom Elements Custom elements let you use your own HTML tags in Blocks widgets. These elements work across all supported browsers, and can be used with any JavaScript ES6 library or framework that works with HTML 5. **With custom elements, you can:** * Design elements with additional functionality or CSS capabilities. * Embed any widget that requires full DOM access. **Code requirements:** * Your code must be up to date and HTML5 compatible. You should transpile your JS to ES2020. * If you are hosting your own code, it must be hosted over a secure protocol (HTTPS). Also, all HTTP calls from the code needs to be to HTTPS endpoints. * If you are hosting your own code, all relevant design settings and complex functionalities (for example the CSS and other JS files), must be bundled in a single JS file. Don’t set anything in a separate file. > **Note:** A site does not need a premium account or a domain to use a Blocks app with a custom element. * * * ## Step 1 | Adding and Setting Up a Custom Element Add as many custom elements as you need to your widget. After dragging a custom element to your widget, define its source (server URL or a [Velo file](https://support.wix.com/en/article/velo-about-custom-elements)) and give it a tag name to appear in the page registry. The tag name should be the exact name used in the `customElement.define()` function.
**Tips** * To see how the custom element looks live, install your app on a site and go to the published site. This is because, for security reasons, the custom element is rendered inside an iFrame in the site-editor and in preview mode, which might affect the layout. * You can define your element's SEO settings using the [Custom Element SEO Markup property](https://www.wix.com/velo/reference/$w/customelement/seomarkup).* * * ## Step 2 | Adjust the Custom Element by Setting Attributes The custom element HTML attributes let you adjust your element according to parameters that you control. For example, you can set dynamic texts or change colors on the go, or change the custom element inner logic according to the widget’s instance on a specific site. > Make sure that the script of your custom element **acknowledges and handles** these attributes. Otherwise, they won't function properly. There are two ways to initiate your custom element's attributes in the Blocks app: **A. Click Set Attributes:** Set and initiate your element’s attributes by adding them to this designated panel. You can also edit or remove the attributes later. 1. Click **Set Attributes** on the custom element. 2. Click **New Attribute**. 3. Enter a name for the attribute, for example, `title`. 4. Enter the value for the attribute (it can be any relevant string). **B. Use Code:** Set your element’s attributes in the widget code with the [`setAttribute()`](https://www.wix.com/velo/reference/$w/customelement/setattribute) function. For example, you can pass the [app's instance ID](https://dev.wix.com/docs/sdk/backend-modules/app-management/app-instances/get-app-instance.md) to the custom element: ### Backend ```js import { webMethod, Permissions } from "@wix/web-methods"; import { auth } from "@wix/essentials"; import { appInstances } from "@wix/app-management"; export const getInstance = webMethod(Permissions.Anyone, async () => { try { const elevatedGetAppInstance = auth.elevate(appInstances.getAppInstance); const response = await elevatedGetAppInstance(); return response; } catch { console.log("error"); } }); ``` ### Widget code ```js import { getInstance } from "backend/instance.web"; $w.onReady(async function () { try { const response = await getInstance(); $w('#myCustomElement').setAttribute('instanceIdAttribute', response.instance.instanceId); } catch (error) { console.log("Error getting instance:", error); } }); ```
**Tip:** If you only need to refer to the custom element's attributes inside this widget, there is no need to connect it to the widget API or add a panel.### Add a property to the widget API 1. Click the **Widget API**  icon on the bottom of your Blocks screen. 2. Click **Add New Property** or hover over **Properties** and click the  icon. 3. Name your property, select its [type](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/widget-api/blocks-widget-properties.md) and default values, add a description. 4. Click **Create.** ### Set the attribute in the onPropsChanged() and onReady() functions Define your widget's [onPropsChanged() function](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-blocks/widget-api/blocks-widget-properties.md#defining-onpropschanged) and `onReady()` functions to handle a change in this property. For example, let's say we added a property named `title`, which enables the user to change the title of the custom element. The code below sets the custom element attribute `title` to be the same as the widget's property `title`. Creating a function to apply props and using it in both the `onPropsChange()` and `onReady()` events, helps you avoid problems when your props aren't applied in preview mode, or other similar situations. ```javascript $widget.onPropsChanged((oldProps, newProps) => { applyProps(newProps) }); $w.onReady(function () { applyProps($widget.props) }); function applyProps(props) { $w('#customElement1').setAttribute('title', props.title); } ``` ### Optional: create a panel to change the property [Create a custom panel](https://support.wix.com/en/article/wix-blocks-designing-custom-panels-for-your-widgets-action-bar-buttons) that allows a site creator who installed your app to be able to change the widget properties (and therefore, the custom element attributes). 1. Click the **Panels** tab at the top of Blocks. 2. Click **Create New Panel**, or open a custom panel that you already created. 3. Add an element that can receive a the new property (in our example, it's an input element named **'panelTextInput1'**). 4. Open the designated code area in the **Panels** tab. 5. Add code that will pass the property from the panel to the widget (in our example, it goes both ways): ```javascript import { widget } from '@wix/editor'; $w.onReady(async function () { const titleValue = await editor.widget.getProp('title'); $w('#panelTextInput1').value = titleValue; $w('#panelTextInput1').onChange(async () => { await widget.setProp('title', $w('#panelTextInput1').value); }); }); ```
Tip: When creating a custom-element-only widget, it’s best practice to make it 100% of a widget and define it as non-selectable in the Configuration tab, so that when a site builder clicks on the widget to configure its settings, they will not click on the custom element.