This is a repo which is useful for Craft CMS in its headless configuration with using the plugin formie. It allows you to simply install the dependencies, style your components without further configuration.
If you are using the File Input, please be sure to enable mutation (creation) of assets in your graphql schema.
In your frontend code run
npm install svelte-craftcms-headless-formie
Enable Views for the formie forms and creation of submission in the graphql schema.
In your svelte file, import the component. And add the form handle and the public CMS API url. The Form handle can be passed in dynamically, as the form will be fetched client side.
<script lang="ts">
import { PUBLIC_CMS_API } from '$env/static/public';
import FormieForm from 'svelte-craftcms-headless-formie';
</script>
<FormieForm handle="your-form-handle" publicCmsApi={PUBLIC_CMS_API} />
You can pass in multiple snippets:
Prop | Description | type | default |
---|---|---|---|
handle |
the form handle | string (required) |
- |
submitButton |
your custom submitButton (type="submit") | Snippet (required) |
- |
publicCmsApiKey |
the cms api url, where the submission has to be sent to | string (required) |
- |
siteId |
siteId, which the submission should be submitted to. | string | number | undefined |
undefined |
recaptchaKey |
if recaptcha is setup in formie, pass in the recaptcha key | string | undefined |
undefined |
isLoading |
allows you to bind to a loading state during the submission | boolean | undefined |
false |
class |
optional classes will can be directly used to style the <form> element |
string | undefined |
'' |
skeletonSnippet |
renders a skeleton loader snippet | Snippet | undefined |
undefined |
afterSubmitSnippet |
renders a snippet after the submission. The message displayed will contain the elements from craft formie. | Snippet | undefined |
undefined |
errorSnippet |
renders an error snippet if an error is caught during inititial render. In contrary to afterSubmitSnippet , this Snippet will allow you to render totally custom components. |
Snippet | undefined |
undefined |
pagination |
Snippet used to display UI relevant with multistep forms | Snippet |
undefined |
recaptchaHint |
renders a snippet as a hint for recaptcha. Will only be shown, if a recaptchaKey is provieded | Snippet | undefined |
recaptchaHintSnippet.svelte |
onaftersubmit |
callback fired after submit. The event passed contains a message (defined in formie) aswell as the error state | (message: string | null, isSuccess: boolean) => void | undefined |
undefined |
If you have a multistep form, use the multistep snippet, to display further information:
{#snippet pagination({ currentIndex, totalPages, backBtn, nextBtn })}
<div>
{currentIndex + 1} / {totalPages}
{#if backBtn}
<button type="button" onclick={backBtn.onclick}>{backBtn.text}</button>
{/if}
{#if nextBtn && currentIndex + 1 !== totalPages}
<button type="button" onclick={nextBtn.onclick}>{nextBtn.text}</button>
{/if}
</div>
{/snippet}
Be aware, that a type="button"
for pagination buttons is necessary. Otherwise, the form will be submitted before reaching the end.
In your main css file just apply all the styles to the input fields.
<FormieForm/>
Component does have a structure like this:
<form data-formie-form>
<div data-form-page="1">
<!-- the number resemblences the current form page -->
<div data-formie-field>
<!-- wrapper for each input -->
<div data-formie-field-single-line-text>
<!-- data-attribute for top html element of given input type -->
...
</div>
</div>
</div>
</form>
The data-formie-field-*
attribute stands for the top html element of a given input type. Those are the available data-attributes:
data-formie-field-address
data-formie-field-agree
data-formie-field-checkboxes
data-formie-field-date
data-formie-field-dropdown
data-formie-field-email
data-formie-field-heading
data-formie-field-multi-line-text
data-formie-field-name
data-formie-field-number
data-formie-field-phone
data-formie-field-radio
data-formie-field-single-line-text
data-formie-field-fileupload
data-formie-recaptcha-hint
data-formie-field-error
Those data-attributes can be used to selectively target the fields / elements.
[data-formie-field-email] {
border: solid 1px black;
}
When a submission is not returned with errors from Craft CMS, the regarding input fields will be automatically set with an aria-invalid="true"
flag. On resubmit, this will be set to false.
This can be used to style invalid form-fields:
[data-invalid='true'],
[data-formie-field-error] {
color: red;
}
<script lang="ts">
import { FormieForm } from '$lib/index.js';
let isLoading = $state(false);
</script>
<FormieForm
handle="your-form-handle"
publicCmsApi="https://your-graphql-endpoint.dev"
onaftersubmit={(e) => console.log(e)}
bind:isLoading
>
{#snippet skeletonSnippet()}
this is a skeleton fallback
{/snippet}
{#snippet submitButton({ text })}
<button>{text}</button>
{/snippet}
{#snippet afterSubmitSnippet({ state })}
<p style="color: {state.isSuccess ? 'green' : 'red'}">
{state.message}
</p>
{/snippet}
{#snippet errorSnippet()}
<p>This is an error message</p>
{/snippet}
</FormieForm>
Currently, only the following formie Fields are supported:
Be sure to enable / disable those fields accordingly in your formie settings.