When users customize sections through the theme editor, the HTML of those sections is dynamically added, removed, or re-rendered directly onto the existing DOM, without reloading the entire page. However, any associated JavaScript that runs when the page loads won't run again. Additionally, you must make sure that when a section or block is selected, that section or block becomes, and remains, visible while it’s selected. For example, a slideshow section should scroll into view when the section is selected, slide to a selected block (slide), and pause while that block is selected. To help identify theme editor actions like section and block selection or reordering, you can use the [JavaScript events](#javascript-events) emitted by the theme editor. You might also want to prevent specific code from running in the theme editor. To do so, you can use Liquid and JavaScript variables for [detecting the theme editor](#detect-the-theme-editor). > Tip: > Section files must define [presets](/docs/storefronts/themes/architecture/sections/section-schema#presets) in their schema to support being added to JSON templates using the theme editor. Section files without presets should be included in the JSON file manually, and can't be removed using the theme editor. > Tip: > To learn more about how to make sure your theme is compatible with the [theme editor preview inspector](https://help.shopify.com/manual/online-store/themes/customizing-themes/edit#preview-inspector), refer to [Theme editor preview inspector best practices](/docs/storefronts/themes/best-practices/theme-editor-preview-inspector). ## JavaScript events To identify sections and blocks, the theme editor looks for specific data attributes on the parent element of the associated section or block. Sections are wrapped by a Shopify-generated element which includes this attribute by default. However, blocks need to have the attribute added manually using the `shopify_attributes` property of the [`block` object](/docs/api/liquid/objects/block#block-shopify_attributes). The theme editor emits section and block JavaScript events that bubble, and are not cancellable. Each event has a target (`event.target`), which is either the associated section or block element based on the data attribute mentioned above. In addition to section and block events, the theme editor also emits events for when the [theme editor preview inspector](https://help.shopify.com/manual/online-store/themes/customizing-themes/edit#preview-inspector) is activated or deactivated. The following table outlines the events emitted by the theme editor: <table> <thead> <tr> <th>type</th> <th>target</th> <th>detail</th> <th>Trigger</th> <th>Expected action</th> </tr> </thead> <tbody> <tr> <td><code>shopify:inspector:activate</code></td> <td>-</td> <td>-</td> <td>The theme editor preview inspector has been activated.</td> <td></td> </tr> <tr> <td><code>shopify:inspector:deactivate</code></td> <td>-</td> <td>-</td> <td>The theme editor preview inspector has been deactivated.</td> <td></td> </tr> <tr> <td><code>shopify:section:load</code></td> <td>section</td> <td><code>{sectionId}</code></td> <td>A section has been added or re-rendered.</td> <td>Re-execute any JavaScript needed for the section to work and display properly, as if the page had just been loaded.</td> </tr> <tr> <td><code>shopify:section:unload</code></td> <td>section</td> <td><code>{sectionId}</code></td> <td>A section has been deleted or is being re-rendered.</td> <td>Clean up any event listeners, variables, etc., so that nothing breaks when the page is interacted with and no memory leaks occur.</td> </tr> <tr> <td><code>shopify:section:select</code></td> <td>section</td> <td> <pre><code>{<br/> sectionId,<br/> load</br>}</code></pre> </td> <td>The user has selected the section in the sidebar.</td> <td> The theme editor automatically scrolls to the section, so make sure the section is in view, and stays in view, while selected. </td> </tr> <tr> <td><code>shopify:section:deselect</code></td> <td>section</td> <td><code>{sectionId}</code></td> <td>The user has deselected the section in the sidebar.</td> <td></td> </tr> <tr> <td><code>shopify:section:reorder</code></td> <td>section</td> <td><code>{sectionId}</code></td> <td>A section has been reordered.</td> <td></td> </tr> <tr> <td><code>shopify:block:select</code></td> <td>block</td> <td> <pre><code>{<br/> blockId,<br/> sectionId,<br/> load</br>}</code></pre> </td> <td>The user has selected the block in the sidebar.</td> <td> The theme editor automatically scrolls to the section, so make sure the block is in view, and stays in view, while selected. </td> </tr> <tr> <td><code>shopify:block:deselect</code></td> <td>block</td> <td> <pre><code>{<br/> blockId,<br/> sectionId</br>}</code></pre> </td> <td>User has deselected the block in the sidebar.</td> <td></td> </tr> </tbody> </table> In the table above, `blockId` represents the [block ID](/docs/api/liquid/objects/block#block-id), `sectionId` represents the [section ID](/docs/api/liquid/objects/section#section-id), and `load` indicates whether the event is being triggered by a section re-render, or a user selection. The value of `load` is `true` or `false`. > Tip: > Refer to the [`theme-editor.js` asset](https://github.com/Shopify/dawn/blob/main/assets/theme-editor.js) in Dawn for examples of how the theme editor JavaScript events can be used. ## Detect the theme editor You can detect whether you’re in the theme editor in [Liquid](#liquid-detect-editor) and [JavaScript](#javascript-detect-editor). ### <a name="liquid-detect-editor"></a>Liquid The Liquid [`request` object](/docs/api/liquid/objects/request#request-design_mode) has a `design_mode` attribute that will return `true` if you’re in the theme editor, and `false` if not. For example: ```liquid {% if request.design_mode %} <!-- This will only render in the theme editor --> {% endif %} ``` ### <a name="javascript-detect-editor"></a>JavaScript In JavaScript, the global variable `Shopify.designMode` will return `true` if you’re in the theme editor, and `undefined` if not. For example: ```js if (Shopify.designMode) { // This will only render in the theme editor } ``` ## Detect the theme editor preview inspector In addition to the [JavaScript events](#javascript-events) that are triggered when the theme editor preview inspector is activated or deactivated, you can use the global variable `Shopify.inspectMode`. It will return `true` if the preview inspector is activated, and `false` if not. For example: ```js if (Shopify.inspectMode) { // This will only execute if the theme editor preview inspector is currently activated } ``` ## Detect the theme editor visual preview You can detect whether you’re in the theme editor visual preview in [Liquid](#liquid-detect-preview) and [JavaScript](#javascript-detect-preview). ### <a name="liquid-detect-preview"></a>Liquid The Liquid [request object](/docs/api/liquid/objects/request#request-visual_preview_mode) has a `visual_preview_mode` attribute that returns `true` if you’re in the theme editor visual preview, and `false` if not. For example: ```liquid {% if request.visual_preview_mode %} <!-- This will only render in the theme editor visual preview --> {% endif %} ``` ### <a name="javascript-detect-preview"></a>JavaScript The global variable `Shopify.visualPreviewMode` will return `true` if you're in the theme editor's visual preview, and `undefined` if not. For example: ```js if (Shopify.visualPreviewMode) { // This will only execute inside the theme editor's visual preview } ```