Mount Scripts

Mount scripts add client-side behavior when template logic is not enough. A mount script is a <script mount> block in a component or a page. It runs in the browser after rendering, and this points to the element it belongs to.

A component can have both blocks. Use <script> for template values and <script mount> for interactivity.

A page mount script works the same way. There this points to the page's <body>, and the values declared in the page's plain <script> are in scope. Use a component when the behavior belongs to a block you reuse, and the page when it belongs to the page as a whole.

A page may hold only one, and it has to sit directly in the page. One inside a <div>, a loop or a component tag is refused when the page is built. The editor builds the page as you edit, so the error shows up there right away. A component's own mount script can sit anywhere in the component.

When to use mount scripts

Use them for behavior that should happen once the component is on the page.

Basic pattern

Keep markup and style in the template, and add behavior in one mount block.

<div class="counter">
  <button type="button">0</button>
</div>

<script mount>
  const button = this.querySelector('button');

  button.addEventListener('click', () => {
    button.textContent = Number(button.textContent) + 1;
  });
</script>

The script runs once for each instance of the component, so each one keeps its own state.

Use component values in mount scripts

$props and $context are not available inside <script mount>. Declare what you need in the regular <script> block and use those variables in the mount script.

<!-- ButtonBadge.html -->
<script>
  const { label = 'Open' } = $props;
</script>

<button type="button">{label}</button>

<script mount>
  this.setAttribute('data-label', label);
</script>

Use external libraries

Mount scripts can import npm packages, so you can bring in existing libraries for charts, sliders, animations, analytics and other client-side behavior.

<script mount>
  import confetti from 'canvas-confetti';
  const button = this.querySelector('button');

  button.addEventListener('click', () => {
    confetti();
  });
</script>

An import turns the mount script into a module. Add every npm package it imports to package.json. In the Lediv app that is all it takes, because the dependencies are resolved for you. Locally, install them before you run or build.

Publishing refuses a mount script that imports. Publishing from Lediv installs no dependencies and bundles nothing, so a mount script with an import statement stops the publish, whether it imports an npm package or a URL. A Preview link is built the same way, so it stops too. The script still runs in Preview mode and in an exported project, so download the project and deploy the built output when you need one.

Framework components

You can mount framework components, from React, Svelte, Vue and others, inside a Lediv component to reuse existing libraries.

React example

A minimal React example, for demonstration only.

<!-- MUIButton.html -->
<div class="mui-demo"></div>

<script mount>
  import React from 'react';
  import { createRoot } from 'react-dom/client';
  import Button from '@mui/material/Button';

  const root = createRoot(this.querySelector('.mui-demo'));
  root.render(
    React.createElement(
      Button,
      { variant: 'contained', onClick: () => alert('clicked') },
      'Click me',
    ),
  );
</script>

Declare its dependencies in package.json as above. Keep this approach as a last resort. Extra framework runtimes add JavaScript weight and can slow loading, so prefer native HTML and CSS, like Lediv components without mount scripts, whenever possible.

Good to know


Next steps