Description: The x-cloak directive in AlpineJS helps you hide Alpine-controlled elements until AlpineJS has fully initialized and styled them. This prevents a "flash of unstyled content" (FOUC), where users might briefly see pre-render states or raw template markup before AlpineJS takes over the rendering.
The primary tools for preventing FOUC with AlpineJS are the x-cloak attribute and a corresponding CSS rule.
x-cloak attribute:
This is a directive you add directly to an HTML element. When AlpineJS initializes a component that contains an element with x-cloak, it will automatically remove this attribute from the element. The element (and its children) will remain hidden by the CSS rule until Alpine has finished its initial processing and rendering for that part of the DOM.
<div x-data="{ showContent: true }" x-cloak>
This content is hidden until AlpineJS processes it.
</div>
[x-cloak] { display: none !important; }
This CSS rule is essential. The x-cloak attribute itself doesn't hide anything; it's merely a marker. This CSS rule targets any element that currently has the x-cloak attribute and hides it using display: none. The !important flag is often recommended to ensure this rule takes precedence over other display-related CSS rules that might be applied to the element, preventing them from accidentally making the element visible before Alpine is ready.
You must include this CSS in your project, either in a global stylesheet or within a <style> tag in your HTML's <head> (as done in this example):
[x-cloak] {
display: none !important;
}
Once AlpineJS initializes the component and is ready to show the content, it removes the x-cloak attribute. Since the element no longer has the x-cloak attribute, the CSS rule [x-cloak] { display: none !important; } no longer applies, and the element becomes visible as AlpineJS intends it.
[x-cloak]:
This is the most common pitfall. The x-cloak attribute on its own does absolutely nothing to hide content. It's merely a hook for the CSS. Without the [x-cloak] { display: none !important; } rule in your CSS, elements with x-cloak will be visible from the start, and you'll still experience FOUC. AlpineJS will remove the attribute, but since it was never hidden, there's no change in visibility.
x-cloak unnecessarily to static elements:
x-cloak is designed for elements whose content or display is managed or significantly altered by AlpineJS during its initialization phase (e.g., elements with x-if, x-for, x-show, or those whose content is dynamically set by x-text or x-html from data that might not be immediately available). Applying x-cloak to purely static HTML content that Alpine doesn't interact with offers no benefit. In fact, it might slightly delay the display of that static content because Alpine still needs to process the page and remove the x-cloak attribute, even if there's no other Alpine-driven change to that element.
x-cloak CSS with less specific rules or conflicting styles:
The !important in display: none !important; is generally recommended for the [x-cloak] rule to give it high precedence. However, if elements are still flashing or appearing unexpectedly, double-check your stylesheets. Another CSS rule with higher specificity or another !important rule could potentially override your x-cloak style. Ensure your [x-cloak] rule is loaded and not being inadvertently overridden. For example, an inline style="display: block !important;" on the same element would override the [x-cloak] stylesheet rule.
This example demonstrates the effect of x-cloak. We simulate a small delay in AlpineJS component initialization.
Observe the difference between the list rendered without x-cloak and the list rendered with x-cloak.
x-cloak)You might briefly see the "Raw HTML..." placeholder text below before Alpine replaces it. This is FOUC.
x-cloak
This list uses x-cloak on the <ul>. The "Raw HTML..." placeholders should not be visible at all.
(Status updated by AlpineJS)
The x-init in the component simulates a 700ms initialization delay to make FOUC more observable.