Skip Navigation

Demo & Example

You can find the open-source example integration of DreamForm on GitHub. This example uses HTMX for progressively enhancing form submissions and Tailwind CSS for styling the form.

To keep things simple, we're using the CDN versions of both tools. If you're deploying a site with Tailwind in production, make sure to add a build step for Tailwind CSS.

Get up and running

Download or clone the repository from GitHub and switch into the created directory.

git clone df-plainkit && cd df-plainkit

Install Kirby 4, DreamForm and other utility plugins (like DotEnv for environment variables & Ray for debugging) using Composer. If you don't have Composer yet, follow the installation guide on the Composer website.

composer install

Copy the .env.example file to .env and add a randomly generated secret that is used for encrypting the snippet parameters for use with HTMX.

After that, you're ready to go: start the PHP dev server with composer as well. You'll now be able to open the DreamForm site in your browser under http://localhost:8000.

composer start

The Demo Explained


This template is rendered when opening the page in your browser. It contains a call to the layout snippet which renders the HTML shell and some general markup. The important part is the call to the dreamform/form snippet. In here, all attached classes are specified and the form is rendered.

    /* Render the form selected in the page */
    snippet('dreamform/form', [
      'form' => $page->form()->toPage(),
      'attr' => [
        'row' => ['class' => 'gap-4 mb-4'],
        'field' => ['class' => 'group flex flex-col items-start mb-4 last:mb-0'],
        'label' => ['class' => 'text-sm font-medium text-slate-600 mb-1'],
        'input' => ['class' => 'peer group-data-[has-error]:placeholder-shown:mb-2 shadow-sm group-data-[has-error]:placeholder-shown:border-red-500 w-full border border-gray-200 rounded p-2'],
        'button' => ['class' => 'ml-auto bg-indigo-600 text-white py-2 px-4 rounded shadow-sm hover:bg-indigo-800 transition-colors duration-200'],
        'error' => ['class' => 'peer-[:not(:placeholder-shown)]:hidden text-red-500 text-sm'],
        'radio' => [
          'label' => ['class' => 'text-sm font-medium text-slate-600 mb-2'],
          'input' => ['class' => 'w-4 rounded-full mr-2 shadow-sm border border-gray-200 '],
          'error' => ['class' => 'group-has-[:checked]:hidden text-red-500 text-sm'],
          'row' => ['class' => 'flex items-center mb-1 text-sm'],
        'checkbox' =>  [
          'label' => ['class' => 'text-sm font-medium text-slate-600 mb-2'],
          'input' => ['class' => 'w-4 mr-2 shadow-sm border border-gray-200 rounded'],
          'error' => ['class' => 'group-has-[:checked]:hidden text-red-500 text-sm'],
          'row' => ['class' => 'flex items-center mb-1 text-sm'],
        'file' => [
          'input' => ['class' => 'mt-1 w-full border border-gray-200 group-data-[has-error]:mb-2 group-data-[has-error]:border-red-500 text-gray-600 shadow-sm rounded file:cursor-pointer file:transition-colors file:bg-gray-100 file:border-0 file:mr-3 file:py-2 file:px-4 file:hover:bg-gray-200'],
          'row' => ['class' => 'flex items-center mb-1 text-sm'],
    ]); ?>


The corresponding Page blueprint for that template is located here. It uses the dreamform/fields/form panel field that can be used to select a form. The stored value is then rendered by the template above.

title: Default Page

    width: 2/3
        type: fields
              inline: false
            type: writer
            inline: true
          form: dreamform/fields/form
    width: 1/3
        type: pages
        template: default
        type: files


This file is the user blueprint for the editor role. We want our editors to not be able to create or update forms, but they should be able to view submissions and forms. This is done by setting the DreamFormn permissions here. By default, all users have access to all permissions. You can read more about Permissions here.

title: Editor
    "*": false
    accessForms: true
    accessSubmissions: true


This is a basic layout snippet that renders the site scaffolding. It's used as Kirby snippet with slots.


This is a custom success snippet shown after a successful form submission. You can generally override all DreamForm snippets by putting a equally named part in your /site/snippets folder.


This is the field snippet for the custom LinkedIn field we defined in /site/plugins/dreamform-demo/LinkedInField.php. To not copy any code from the plugin, we're simply rendering the built-in DreamForm text field snippet here, since the LinkedIn field just adds custom validation rules.


This is a custom field that validates LinkedIn Profile URLs, used in our example Job application form. The HTML snippet can be found above. You can read more about building your own custom fields here.


This file registers our custom LinkedIn field with DreamForm as well as registers the plugin with Kirby.


This is our Kirby config file. It sets some important defaults for using DreamForm, such as our HTMX mode or removing the CSRF guard so we can be accept form submissions on cached websites.