Installation
Quiet UI features 88 high-quality, accessible, interoperable components, a modern theme with light and darks modes that can adapt to any brand, an optional CSS reset, and more!
There are two ways to install Quiet components. Autoloading is the fastest way to get started — just copy, paste, and start coding. Or you can import components manually from a self-hosted distribution.
Autoloading Recommended
Jump to heading
Copy and paste the following code into the <head> section of any HTML document. The
autoloader will fetch components from the CDN as you add them to the DOM.
<!-- Quiet theme + autoloader --> <link rel="stylesheet" href="https://cdn.quietui.org/v2.0.0/themes/quiet.css"> <script type="module" src="https://cdn.quietui.org/v2.0.0/quiet.loader.js"></script> <!-- Optional CSS reset --> <link rel="stylesheet" href="https://cdn.quietui.org/v2.0.0/themes/restyle.css">
Permission is required to use the private CDN. Logs are monitored and unauthorized origins will be blocked without notice.
Now you can use any component in your HTML!
<quiet-button variant="primary"> This is amazing </quiet-button>
Discovery complete Jump to heading
As a convenience, Quiet's autoloader emits an event called quiet-discovery-complete when all
elements on the page have been "discovered" and registered. This is useful if you want to show,
for example, a loading indicator until all components are registered.
document.addEventListener('quiet-discovery-complete', event => { // All custom elements have been registered! }, { once: true });
You can inspect event.detail.registered to see an array of tag names that were found and
registered. Similarly, event.detail.unknown will be an array of
<quiet-*> tags that were found in the document but couldn't be registered. This can
happen if you use the wrong tag name, if the files are missing, or if you're trying to use new components
with an older version of the library.
Reducing FOUCE Jump to heading
Custom elements are registered with JavaScript, so you might experience FOUCE on page load as the autoloader fetches components.
To reduce FOUCE, add the quiet-cloak class to the <html> element as shown
below. Avoid adding the class with JavaScript — it needs to be present when the browser first renders the
page to work properly.
<html class="quiet-cloak"> ... </html>
As soon as all components are defined or after two seconds elapse, the content will be shown and the class will be removed, eliminating most FOUCE. The two second timeout ensures users don't see a blank page even when networks are slow or have problems.
Hotwire: Turbo users
Many multi-page applications (MPAs) use Hotwire: Turbo to provide a SPA-like experience for users. When visiting links, Turbo intercepts the click, fetches the new page, and updates metadata and content without redirecting, resulting in a buttery smooth transition when going from one page to another.
However, when you use Turbo with Quiet's autoloader, you may see FOUCE when visiting new pages for the first time. This is because Turbo renders the new page and then the autoloader fetches unregistered components.
To solve that, call the preventTurboFouce() function in your app. The function adds a
listener that hooks into Turbo's turbo:before-render event and registers all components
before the new page is rendered, effectively eliminating FOUCE for page-to-page navigation.
The function accepts one argument: an optional timeout in milliseconds to prevent issues with errors or
slow networks. For most use cases, the default value of 2000 is optimal.
import { preventTurboFouce } from '/dist/quiet.js'; preventTurboFouce();
Preloading components Jump to heading
You can tell the autoloader to preload components that aren't initially on the page by adding the
data-quiet-preload attribute anywhere in the document. Tags must be separated by a space, as
shown below. A good practice is to add it to the <html> element.
<!-- This will load <quiet-button> and <quiet-tooltip> even if they're not on the page at first --> <html data-quiet-preload="quiet-button quiet-tooltip"> ... </html>
Manually importing Advanced
Jump to heading
If you don't want to use the autoloader, you can import components manually from a self-hosted distribution.
Add the default theme and the optional CSS reset to your HTML:
<!-- Quiet styles --> <link rel="stylesheet" href="/path/to/quiet/dist/themes/quiet.css"> <!-- Optional CSS reset --> <link rel="stylesheet" href="/path/to/quiet/dist/themes/restyle.css">
Quiet ships standard ES modules, so you can use
import
or
import()
to pull in exactly the components and utilities you need.
// Static imports are the most common import '/path/to/quiet/dist/components/badge/badge.js'; import '/path/to/quiet/dist/components/button/button.js'; import '/path/to/quiet/dist/components/card/card.js'; // ...but you can also import components dynamically await Promise.all([ import('/path/to/quiet/dist/components/badge/badge.js'), import('/path/to/quiet/dist/components/button/button.js'), import('/path/to/quiet/dist/components/card/card.js') ]);
The imports above are just examples. You can copy and paste the import code for each component you need from the Importing section of the docs.
Setting the library path Jump to heading
Quiet uses something called the library path to load components and assets at runtime. It will try
to guess the library path by looking for a script called quiet.js or
quiet.loader.js on the page. If you're using the CDN or consuming the library in a similar way,
you can probably skip this section.
If you're using a bundler, you will need to create a task that copies Quiet's
dist folder into your project and set the library path to point to there.
You can set the library path by adding the data-quiet attribute to any element on the page.
<html data-quiet="/path/to/quiet/dist">
Alternatively, you can set it programmatically using the setLibraryPath() function.
import { setLibraryPath } from '/path/to/quiet.js'; setLibraryPath('/path/to/quiet/dist');
If components or icons aren't loading, make sure you've copied the necessary files into your project and set the library path correctly!