Skip to content
Zero configuration Preact widgets renderer in any host DOM
Branch: master
Clone or download
Latest commit 97e7261 Aug 9, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples/login-form Fix example page Aug 9, 2019
src Add application/json test Aug 9, 2019
.babelrc rollup es + umd + tested Aug 10, 2017
.editorconfig jest tests 86% (stmts) - 100% (funcs) coverage Aug 9, 2017
.gitignore Allow application/json script type Aug 3, 2019
.travis.yml use default user preact, module + travis updates May 31, 2017
LICENSE license: personal website added Aug 13, 2017 Change default script type to application/json Aug 9, 2019
package-lock.json 3.3.0 Aug 9, 2019
package.json 3.3.0 Aug 9, 2019
rollup.config.js selector as a render object option w/ docs update Aug 13, 2017

Build Status Code Coverage downloads version gzip size module formats: umd, cjs, and es Supports Preact and React MIT License

Preact Habitat

A 900 Bytes module for that will make plugging in Preact components and widgets in any CMS or website as fun as lego!


Login Widget Source Code 💻

Login Widget Integration pen Codepen Demo 🖋


npm install --save preact-habitat

Core Features

  • 2 ways to passing props from DOM.
  • Multiple rendering options.
  • Light weight ( < 1KB ).
  • Compatible with React widgets through preact-compat.
  • In use in high traffic web applications.

Basic Usage Example

import habitat from 'preact-habitat';
import WidgetAwesome from './components/WidgetAwesome';

const { render } = habitat(WidgetAwesome);

** other selecors options:
** ".classname"  for querying DOM element by its class name
** "#div-id"  for querying DOM element by its ID value
** "[data-attribute-example='widget-here']"  for querying DOM element by its data attribute name & val

  selector: '.some-class', // Searches and mounts in <div class="some-class"></div>
  defaultProps: undefined, // Default props for all widgets
  inline: false,
  clean: false,
  clientSpecified: false

in webpack.config.js or any other build tool bundle output format should be UMD:

output: {
  libraryTarget: 'umd'

in the DOM you'd like to mount your widget in:

<div class="some-class"> <!-- as specified in render, habitat will mount the component in this-->
  <script type="application/json">
      "title": "Widget Title passed as prop",
      "theme": "red",
      "anotherProp": "Thanks for trying this widget out!"

Now, build your production ready preact widget and you're all set, TADA! 🎉

API Docs


accepts a single Preact component as its only argument

import { h } form 'preact';
import habitat from 'preact-habitat';

const Widget = () => <h1>Hello, World!</h1>;

const { render } = habitat(Widget); // NOTE: pass Widget and not <Widget />



render function accepts an options Object which supports the following properties:


String: .myclass, #myid, [data-selector="my-data-attr"]

DOM Element selector used to retrieve the DOM elements you want to mount the widget in


Object: {} || undefined (default)

Default props to be rendered throughout widgets, you can replace each value declaring props.


Boolean: true || false (default)

Set to true if you want to use the parent DOM node as a host for your widget without specifing any selectors.


<div class="beautiful-container">
  <!-- inline set to true will make this widget render in it's parent 
      wrapper class="beautiful-container" without using selector option-->
  <script async src="cdn.preactwidget..."></script>


Boolean: true || false (default)

clean will remove all the innerHTML from the HTMl element the widget will mount in.


if we set the widget to be mounted inside the selector ".beautiful-container" with {clean: true} it will remove the Loading div as soon as it renders.

<div class="beautiful-container">
  <div class="loader">LOADING...</div>

<script async src="cdn.preactwidget..."></script>


Boolean: true || false (default)

This option allows who ever using the script to specifit the selector which they'd like to mount the widget in

<div class="beautiful-container">
  <div class="loader">LOADING...</div>

<script async src="cdn.preactwidget..." data-mount-in=".beautiful-container"></script>

Passing Props

There are 2 ways to pass props, either via data-attributes or application/json script tag

via props script

Simply add a <script> tag with type="application/json" or type="text/props" and ensure the content is valid JSON. multiple script tags will be merged together and passed down.

<div class="beautiful-container" data-prop-name="preact habitat" data-prop-version="v3.0.0" data-prop-theme-color="green">
  <script type="application/json">
      "name": "preact habitat",
      "themeColor": "green"

via data-attribute

the data attribute has to always start with data-prop- examples:

data-prop-name will be available in your component as name

data-prop-version will be available in your component as version

data-prop-theme-color will be available in your component as themeColor NOTE the lowerCamelCase when there's a -

<div class="beautiful-container" data-prop-name="preact habitat" data-prop-version="v3.0.0" data-prop-theme-color="green">


MIT - Copyright (c) Zouhir Chahoud


Artwork By: Oleg Turbaba, Dribble

You can’t perform that action at this time.