Components
Leverage HTML templates across your project.
Overview
Components in Manifest are HTML files representing pages, sections, or other UI templates that can be reused throughout a project. Optimized for performance, components are resolved and rendered in milliseconds at browser runtime, eliminating the need for server-side rendering.
Setup
Components are included in manifest.js with all core plugins, or can be selectively loaded. manifest.json is required to register components.
<!-- Meta -->
<link rel="manifest" href="/manifest.json">
<!-- Scripts -->
<script src="https://cdn.jsdelivr.net/npm/mnfst@latest/lib/manifest.min.js"></script><!-- Meta -->
<link rel="manifest" href="/manifest.json">
<!-- Scripts -->
<script src="https://cdn.jsdelivr.net/npm/mnfst@latest/lib/manifest.min.js"
data-plugins="components"></script>Create Components
Create an HTML file anywhere in your project directory, such as /components/header.html. Its filename must be distinct from other components.
<header class="w-full p-4 bg-page border-b border-line">
<strong>Acme</strong>
</header>Components can have any number of top-level elements, like this component home page:
<h1>Welcome!</h1>
<section>...</section>
<section>...</section>All components are rendered as a desendent of the index.html body, and cannot contain their own <body> tag.
Nesting
Provided that a circular reference is not created, components can be recursively nestedโsuch as a logo placed in a header component.
<header class="row items-center gap-2 w-full p-4 bg-page border-b border-line">
<x-logo></x-logo>
</header><svg class="h-7 fill-accent-content" viewBox="0 0 197 48" xmlns="http://www.w3.org/2000/svg">...</svg>Page Head Content
Components can include head content in a <template data-head> tag, which gets appended to the head of any route that includes the component, and removed when the component is no longer rendered.
<template data-head>
<script>
console.log('๐ Component article script loaded');
</script>
</template>Check the console for this page and you should see the above log.
Register Components
HTML files need to be declared in manifest.json due to browser security restrictions.
{
"components": [
"components/home.html",
"components/about.html"
],
"preloadedComponents": [
"components/header.html",
"components/logo.html"
],
...
}Components are registered by custom filepath from the project root in one of two arrays:
componentsis the default array, suitable for components that load on-demand.preloadedComponentsis for components that should load in the background if not already used by a current route, reducing their load time on subsequent navigations.
Note that components are cached after first render for the duration of the session.
Apply Instances
Components are applied with <x-filename> tags, where filename is the actual name of the source file. Top-level components are placed in the index.html body:
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
<!-- header.html -->
<x-header></x-header>
<!-- Page content components like home.html and about.html -->
<main>
<x-home x-route="/"></x-home>
<x-about x-route="about"></x-about>
</main>
<!-- footer.html -->
<x-footer></x-footer>
</body>
</html>See the router plugin for more information on conditional rendering with the x-route attribute.
Customizing Instances
In some scenarios it's useful to diverge an instance's content or styles from the source component, such as modifying the header for a special page.
Isolate the Instance
If the instance is used globally like the earlier header example, we'll need to create an isolated version that can be modified without affecting the others. The x-route attribute can be used to show or hide instances based on the current route.
<body>
<!-- Global header, omitted from the special page -->
<x-header x-route="!special"></x-header>
<!-- Specialty page -->
<x-special-page x-route="special"></x-special-page>
</body><!-- Isolated header instance within the special page -->
<x-header></x-header>
<!-- Other page content -->
...Parent Modification
Modifying just the parent element can be done immediately by adding any new attribute values to the component tag:
<body>
<x-header id="specialHeader" class="!bg-slate-700"></x-header>
...
</body>These attribute values will be added to the first top-level element in the component file. If an attribute like class already exists on that element, the new values are appended to it. Appended Tailwind utility classes meant to override others may require an !important variant.
Child Modification
Modifying child elements requires custom attributes that can be referenced in the instance placeholder tag like <x-header colors="..." wordmark="...">.
These custom attributes are created in the component source file using Alpine directives (dynamic attributes) like x-text, x-html, and x-bind, or Manifest's extended directives like x-icon.
<header class="row items-center gap-2 w-full p-4 bg-stone-400 dark:bg-stone-800 text-stone-50" :class="$modify('colors')">
<span x-icon="$modify('icon')"></span>
<strong x-text="$modify('wordmark')"></strong>
</header>Each directive requires a $modify('...') value with the name of the custom attribute to be exposed. This attribute is subsequently available to all of the component's instances:
<x-header
colors="!text-white !bg-pink-400 dark:!bg-pink-900"
icon="lucide:globe"
wordmark="Universal Exports"
></x-header>If overrides with custom attribute are not required in every instance, place fallback logic in the component source to ensure optimal presentation.
<!-- Static classes apply if not overriden by the colors attribute -->
<header class="row items-center gap-2 w-full p-4 bg-color-400 dark:bg-color-800 text-color-50" :class="$modify('colors')">
<!-- Doesn't render if the instance omits the icon attribute -->
<span x-icon="$modify('icon')" x-show="$modify('icon')"></span>
<!-- Sets "Acme" as a default value if the instance doesn't include the wordmark attribute -->
<strong x-text="$modify('wordmark') ?? 'Acme'"></strong>
</header>Injecting Dynamic Data
Instances can also receive their content from a data source. Simply make the custom attributes dynamic with a leading : and turn the value into a data source reference using $x. In this example, we're referencing an arbitrary content.json source:
<x-header
:colors="$x.content.specialHeader.colors"
:icon="$x.content.specialHeader.icon"
:wordmark="$x.content.specialHeader.wordmark"
></x-header>{
"specialHeader": {
"icon": "lucide:star-half",
"wordmark": "Waystar Royco",
"colors": "!gap-0 [&_strong]:-ml-1 [&_strong]:mb-1 !text-white !bg-neutral-900 dark:!text-black dark:!bg-neutral-100"
},
...
}Article does not exist
There is no documentation at this path.