# Initialization This document covers the different ways to initialize mancha and configure its behavior. ## Choosing the Right Approach Mancha offers three initialization methods. Use this decision guide to choose the right one: | Method | Use When | Complexity | |--------|----------|------------| | **Script Tag** | Simple projects, prototypes, single-page apps with no build step | Lowest | | **ES Module (`initMancha`)** | Projects with bundlers, need for initial state, custom initialization logic | Medium | | **`:render` Attribute** | Initializing specific elements (charts, maps, etc.) within an already-mounted page | Element-level | ### Decision Flowchart ``` START: Do you have a build step (bundler/TypeScript)? │ ├─ NO → Use Script Tag with `init` attribute │ │ └─ YES → Are you initializing the whole page or specific elements? │ ├─ WHOLE PAGE → Use ES Module with `initMancha` │ import { initMancha } from "mancha/browser"; │ await initMancha({ target: "#app" }); │ └─ SPECIFIC ELEMENTS → Use `:render` attribute on those elements ``` ### Quick Reference **Script Tag** (simplest, no build step): ```html ``` **ES Module** (bundlers, TypeScript, custom init): ```typescript import { initMancha } from "mancha/browser"; await initMancha({ target: "#app", state: { count: 0 } }); ``` **`:render` Attribute** (element-level initialization): ```html ``` > [!TIP] > **For AI agents**: Start with the Script Tag approach for simple tasks. Use ES Module when you need to set initial state programmatically or have a build step. Use `:render` only for third-party library integration on specific elements (charts, maps, video players). --- ## Script Tag The simplest way to use mancha is via a script tag with the `init` attribute: ```html ``` ### Script Tag Attributes | Attribute | Description | Example | |-----------|-------------|---------| | `init` | Enables automatic initialization on page load | `init` | | `target` | CSS selector(s) to mount to (default: `body`). Use `+` to separate multiple targets | `target="main"` or `target="#app+#sidebar"` | | `css` | CSS bundles to inject. `"minimal"` for prose styling, `"utils"` for Tailwind-style utilities (includes CSS reset + on-demand scanning) | `css="utils"` | | `debug` | Enable debug logging | `debug` | | `cache` | Fetch cache policy for includes | `cache="no-cache"` | | `cloak` | Control FOUC prevention (see below) | `cloak="200"` or `cloak="false"` | ## ES Module API For more control, use the `initMancha` function: ```typescript import { initMancha } from "mancha/browser"; const renderer = await initMancha({ target: "#app", css: ["utils"], state: { message: "Hello" }, }); ``` ### InitManchaOptions | Option | Type | Description | |--------|------|-------------| | `renderer` | `Renderer` | Use an existing Renderer instance instead of creating a new one | | `target` | `string \| string[]` | CSS selector(s) to mount to | | `css` | `CssName[]` | CSS bundles to inject: `"minimal"` or `"utils"` (includes CSS reset + on-demand scanning) | | `state` | `Record` | Initial state to set before mounting | | `debug` | `boolean` | Enable debug logging | | `cache` | `RequestCache` | Fetch cache policy for includes | | `cloak` | `boolean \| CloakOptions` | FOUC prevention (see below) | | `callback` | `Function` | Custom initialization callback (see below) | ## Cloaking (FOUC Prevention) Cloaking hides your content until rendering is complete, preventing users from seeing raw template syntax like `{{ variable }}` or `:text="expr"` before JavaScript processes them. ### How It Works Cloaking injects a global ` ``` When `initMancha({ cloak: ... })` runs, it will detect this existing style tag (by its ID `mancha-cloak`) and take control of it, applying any configured transitions and removing it once rendering is complete. ### Keeping Loading Indicator Active To keep the browser's loading spinner active while `mancha` initializes (e.g., fetching data or waiting for cloaking animations), use a module script with top-level await: ```html ``` ### Custom Loading Indicators During initialization (until `initMancha` resolves), `mancha` adds a `mancha-loading` class to the `` element. You can use this class to display a custom loading indicator or overlay while your application is bootstrapping. **Recipe: Full-screen loading overlay** ```css /* Hide the loader by default */ .loader { display: none; } /* Show the loader only while mancha is loading */ html.mancha-loading .loader { display: flex; position: fixed; inset: 0; background: white; z-index: 9999; justify-content: center; align-items: center; } ``` ```html
Loading...
...
``` This works perfectly with cloaking: `mancha-loading` is removed *immediately before* the cloaking fade-in animation starts, ensuring a seamless transition from your custom loader to the rendered app. ## Custom Initialization Callback For advanced use cases, provide a `callback` function. When used, automatic mounting is skipped—you must call `renderer.mount()` yourself: ```typescript import { initMancha } from "mancha/browser"; await initMancha({ cloak: { duration: 150 }, callback: async (renderer) => { // Fetch data before mounting const data = await fetch("/api/data").then((r) => r.json()); await renderer.set("items", data.items); // Mount to the DOM await renderer.mount(document.getElementById("app")); }, }); ``` The callback receives: - `renderer`: The initialized Renderer instance ## Element-Level Initialization with `:render` The `:render` attribute provides element-level initialization by linking an HTML element to a JavaScript ES module. This is useful for initializing third-party libraries (charts, maps, video players) on specific elements. ```html ``` The module's default export is called with the element and renderer: ```js // chart-init.js export default function (elem, renderer) { new Chart(elem, { type: "bar", data: { labels: ["A", "B"], datasets: [{ data: [1, 2] }] } }); } ``` ### When to Use `:render` | Use `:render` When | Don't Use `:render` When | |--------------------|--------------------------| | Integrating third-party libraries (Chart.js, Leaflet, etc.) | Initializing the entire page | | Element needs imperative JavaScript setup | Simple reactive data binding suffices | | Canvas, video, or other media elements | Standard form inputs and displays | | You need access to the DOM element directly | Pure declarative templates work | ### Key Characteristics - **Runs after mount**: The init function executes after mancha has mounted the element - **SSR compatible**: During server-side rendering, the path is resolved but the module is not executed - **Relative paths**: Paths are resolved relative to the template file, not the HTML page - **Reactive access**: The init function receives the renderer instance for reactive state access For complete documentation on `:render` including reactive state access and custom components, see [Components & Preprocessing](./04_components.md#initialization-with-render). ## Combining Initialization Methods You can combine the Script Tag or ES Module approach with `:render` attributes: **Script Tag + `:render`** (most common for simple projects): ```html

Dashboard

``` **ES Module + `:render`** (for projects with bundlers): ```typescript import { initMancha } from "mancha/browser"; await initMancha({ target: "#app", state: { salesData: await fetchSalesData() }, }); // The :render attributes in #app will execute after mount ``` ```html
``` > [!NOTE] > `:render` scripts execute after `initMancha` or the script tag has mounted the page. They are not a replacement for page-level initialization, but a complement for element-specific setup. ## Advanced: Manual Initialization > [!CAUTION] > This is an advanced API. Most users should prefer `initMancha` which handles CSS injection, state initialization, and FOUC prevention automatically. If you need full control without `initMancha`, you can use the lower-level API directly: ```typescript import { Renderer, injectCss } from "mancha/browser"; // 1. Inject CSS utilities (optional) injectCss(["utils"]); // 2. Create renderer const renderer = new Renderer(); // 3. Set state await renderer.set("name", "World"); // 4. Mount to DOM await renderer.mount(document.body); ``` ## Summary: Initialization at a Glance This table summarizes all initialization methods and when to use them: | Method | Syntax | Use Case | FOUC Prevention | Build Step Required | |--------|--------|----------|-----------------|---------------------| | **Script Tag** | ` ``` **With bundler (ES Module)**: ```html
``` **With third-party chart (Script Tag + `:render`)**: ```html

Sales Dashboard

```