Skip to content

Search tags, filters, functions and guides.

JavaScript API / Host components

JavaScript API

Host components

Render components written in JavaScript, such as React.

A host component is a component written in JavaScript instead of a template. Your loader returns one in place of template source. Use them to render components made with a UI library, such as React or Svelte, from your templates.

import { createKiln, hostComponent, safe } from "@lucidkiln/core";
import { fileLoader } from "@lucidkiln/core/node";

const templates = fileLoader({ root: "src/templates" });

const kiln = createKiln({
	loader: {
		list: templates.list,
		load: (name) =>
			name.endsWith(".tsx")
				? hostComponent(async (props, slots) =>
						safe(await renderReact(name, props, slots)),
					)
				: templates.load(name),
	},
});

Templates use a host component like any other component, by its name. A name with an extension, such as Counter.tsx, keeps it, so the loader can tell which names are host components.

{% component "components/Counter.tsx" with { start: 3 } %}
	<p>Passed in as the default slot</p>
	{% fill "footer" %}<small>Passed in as the footer slot</small>{% endfill %}
{% endcomponent %}

{% include "components/PriceTable.tsx" with { plans: page.plans } %}

What it receives

hostComponent takes a function that Kiln calls each time the component renders. It gets three arguments:

  • props is a plain object holding the hash passed with with, or the context passed to render.
  • slots holds each slot the caller filled, rendered to safe markup. Content outside any fill is the default slot. A slot the caller didn't fill isn't there.
  • render is the same request data that withRender functions get, such as state, locale and tagCache.

It returns safe markup made with safe, or a promise of it. A plain string is escaped, as it is when a function returns one. An error it throws stops the render with a host-error, like an error from a function.

Where it works

  • With component, include and island, in every island mode.
  • With render and renderStream, which render it as the whole output. A server that renders deferred islands from their manifest renders host components this way.
  • Not with extends or import. A host component has no blocks or macros, so these fail with a not-a-template error.

How it differs from a template

  • Every fill renders before the component, since a UI library needs its children up front. A template component only renders a fill when it reaches the slot, so an add to inside an unused fill adds nothing there.
  • Kiln doesn't check its props. Strict mode's prop checks only apply to templates with a props tag.
  • Kiln keeps the host component your loader returned until you call invalidate, as it keeps templates.

In your editor

List the files your loader returns as host components in kiln.json, so the editor completes their names and props. See Host components in editor support.