Template API Reference

All .marko files expose the same API on their default export. These methods are used to generate an HTML string on the server, and to modify the DOM in the browser.

Template.render(input)

ParameterDefaultDetails
input{}The input object for the template. May also include $global for global state

For use on the server, the .render() API on a Marko template provides an object containing a variety of ways to generate an HTML string. Its first parameter becomes the input available within the template.

Async Iterator

The render result contains an async iterator, which allows consumption through a for await statement.

import Template from "./template.marko";

for await (const chunk of Template.render({})) {
  // send the html chunk somewhere.
}

Pipe

The .pipe() method in the render result object sends an HTML string into a NodeJS stream.Writable.

import Template from "./template.marko";
import http from "node:http";

http
  .createServer((req, res) => {
    // Stream rendered html into the server response.
    Template.render({}).pipe(res);
  })
  .listen(3000);

ReadableStream

The .toReadable() method in the render result object returns a WHATWG ReadableStream. This can be used in environments that support web apis, eg in a web worker.

const webHTMLResponse = new Response(Template.render({}).toReadable(), {
  headers: { "content-type": "text/html" },
});

Thenable

The render result is a thenable, so the .then(), .catch() or .finally() methods return a Promise<string> that resolves with a buffered HTML string. This may be handled implicitly with the await keyword.

const html = await Template.render({});

Note

By using thenable and await, you are opting out of Marko's streaming capabilities.

toString

The result implements a toString() that returns the buffered html synchronously if possible.

const html = Template.render({}).toString();

Caution

If there is any async behavior (i.e. an <await> tag) this method will throw.

Template.mount(input, node, position?)

ParameterDefaultDetails
input{}The input object for the template. May also include $global for global state
nodeundefinedA reference to the DOM node where the template will be rendered
position"beforeend"Location to render the template, relative to node. Value follows the Element.insertAdjacentHTML API

For use in the browser/client, The .mount() API on a Marko template builds up a reactive DOM and inserts it at the specified node and position. The input argument becomes the input available within the template.

template.mount({}, document.body); // append to the body.

Or with a position override

template.mount({}, document.body, "afterbegin"); // prepended to the body

Note

Valid values for position include

  • "beforebegin": Before the element.
  • "afterbegin": Just inside the element, before its first child.
  • "beforeend": Just inside the element, after its last child.
  • "afterend": After the element.

which, if the element is this <p>, can be visualized as

<!-- "beforebegin" -->
<p>
  <!-- "afterbegin" -->
  existing body content
  <!-- "beforeend" (default) -->
</p>
<!-- "afterend" -->

Render Result

The .mount() API returns an object with helpers used update and destroy the instance of the template and DOM that was built.

const instance = template.mount({ name: "foo" }, document.body);

[!Warning] This API is not the recommended way to update/destroy Marko templates. It is primarily intended to be used in exclusively client rendered environments and/or while testing. Instead the reactive system should be used.

instance.update(input)

The .update() method allows providing new input to the instance of the template with a reactive update.

instance.update({ name: "bar" });

This update to the input is applied synchronously.

instance.destroy()

The .destroy() method causes every $signal to be aborted and runs cleanup for the instance.

instance.destroy();

input.$global

When a template is rendered via the render or mount APIs, the input object may specify a $global property which will be stripped off and used as $global within all rendered .marko templates.

Some properties on the $global are picked up by Marko itself and have predefined functionality.

$global.signal

AbortSignal | undefined

When signal is included in $global, Marko will listen to it and automatically clean up any pending async rendering activity when it is aborted.

This is used to, for example, prevent continued rendering after an incoming request is aborted.

$global.cspNonce

string | undefined

This value should be a string that represents a valid csp nonce. Marko will automatically set this value as the nonce on all assets (<script>, <style>, etc) rendered by the template.

$global.renderId

string | undefined

The runtimeId is used to isolate runtimes when there are multiple copies on the same page, and is generally not necessary as @marko/vite and @marko/webpack plugins will automatically provide one based off of the project level package.json name.

$global.runtimeId

string | undefined

The renderId is used to isolate distinct server renders (using the same runtime) and is not automatically set. This value should be set such that all server rendered segments of html have a unique renderId string to avoid conflicts. This is particularly useful for solutions such as micro-frame.


Contributors

Helpful? You can thank these awesome people! You can also edit this doc if you see any issues or want to improve it.