REFERENCE / CORE API

onMount()

Runs fn once, after the nodes built by the current work are in the document — for anything that needs a live node: measuring layout, focus, observers, or handing an element to a third-party library.

Signature

TS
onMount(fn: () => void): void

Parameters

PARAMETERTYPEDESCRIPTION
fn () => void Runs once. Skipped if the scope that registered it was disposed before the nodes were inserted.

The moment that did not exist

A component function runs while its nodes are still detached: it builds a Node and returns it, and only then does someone insert it. Anything that needs layout or focus has no moment to run — until this one. It is a timing primitive on the scope, not a lifecycle phase on a component; there is no onUpdate, because nothing re-renders.

JS
function Editor() {
  let input;
  onMount(() => input.focus());               // the input is in the document now
  return html`<input ref=${(el) => (input = el)} />`;
}

When it fires

mount() drains the queue right after it appends, and every flush drains it at its end — so a component created by a conditional or a list row gets its callback too. A node you append by hand still gets it, through a microtask safety net.

JS
const Row = (item) => {
  let li;
  onMount(() => li.animate([{ opacity: 0 }, { opacity: 1 }], 150));   // WAAPI needs a live node
  return html`<li ref=${(el) => (li = el)}>${item.label}</li>`;
};

With ref

You usually pair it with the reserved ref attribute to get hold of a nested element. A single-root template returns its root element directly, so for the root itself no ref is needed.

Try it

src/islands/onmount.ts
import { signal, onMount, html, mount } from '@amojs.dev/core';

const shown = signal(false);
const measured = signal('');

// a component runs while its nodes are still detached; onMount is the moment they are in the document
const Box = () => {
  let el: HTMLElement;
  onMount(() => {
    const { width } = el.getBoundingClientRect(); // layout exists now
    measured.value = `the box is ${Math.round(width)} px wide — measured inside onMount`;
  });
  return html`<p ref=${(node: HTMLElement) => (el = node)} class="status">a freshly mounted component</p>`;
};

const Demo = () => html`<div class="demo">
  <div class="row">
    <button class="counter" onclick=${() => (shown.value = !shown.value)}>${() => (shown.value ? 'unmount it' : 'mount a component')}</button>
  </div>
  ${() => (shown.value ? Box() : '')}
  <p>${measured}</p>
</div>`;

const host = document.getElementById('demo');
if (host) mount(Demo, host);
live preview● running

See also