Mount Scripts

Mount scripts add client-side behavior to components when template logic is not enough.

In Lediv, a mount script is a <script mount> block inside a component or a page. It runs after rendering in the browser, and this points to the element it belongs to.

<script> and <script mount> can coexist in one component. Use <script> for template values and <script mount> for interactivity.

A page can carry one too, and it works the same way: there this points to the <body> element of that page, and the values declared in the page's plain <script> are in scope. Reach for a component when the behaviour belongs to a block you reuse, and for 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. Not inside a <div>, not inside a loop, and not inside a component tag: those are refused when the page is built, and the editor builds the page as you edit it, so the error shows up there and then. A component has no such limit on where its own mount script sits.

When to use mount scripts

Use mount scripts for behaviors like click handlers, DOM manipulation, or small client-side state updates that should happen after the component is mounted.

Basic pattern

Keep markup and style in the template, then 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>

This script runs for each rendered component instance, so each instance keeps its own local state.

Use component values in mount scripts

Values from the component scope can be used inside mount scripts. Define those values in the regular <script> block, then reference them in <script mount>.

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

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

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

$props and $context are not available directly inside <script mount>. Use regular script variables as the bridge.

Use external libraries

Mount scripts can import external npm packages. This makes it possible to add existing libraries for charts, sliders, animations, analytics, and other client-side behaviors without leaving the component workflow.

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

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

When import is present, the mount script is treated as a module. If the import source is an npm package, the dependency must be added to package.json before 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 stops the publish, whether the source is an npm package or a URL. A Preview link is built the same way, so it stops that too. It 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

It is possible to mount framework components (like React, Svelte, Vue, etc.) inside a Lediv component. This is a powerful way to reuse existing libraries and frameworks in a Lediv project.

React example

Here is a very basic example using React, just for demonstration purposes.

<!-- 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>

Please note that used dependencies must be declared in package.json, and installed if used locally.

Also this kind of approach should be used as a last resort, avoiding extra framework/runtime dependencies that add JavaScript weight and can impact loading and performance. Prefer native HTML/CSS (like Lediv components without mount scripts) behavior when possible.

In the Lediv app, the dependencies are automatically resolved, only need to declare them in package.json.

Good to know


Next steps