# WordPress

> Add an Ikiform form to WordPress with the Custom HTML block, or register a shortcode so any author can place the same form anywhere.

Form plugins handle submissions inside WordPress: their forms post back to your own site, and the plugin stores and emails the result. A plain HTML form pointed at Ikiform skips the plugin, the database and the mail setup, and keeps working on cached pages because it carries no WordPress nonce.

## Who can paste a form

WordPress filters the HTML in posts and pages. For anyone without the `unfiltered_html` capability, it removes `<form>` and `<input>` when the content is saved.

| Site | Who can save a form in a Custom HTML block |
| --- | --- |
| Self-hosted, single site | Administrators and Editors |
| Self-hosted Multisite | Super Admins only |
| `DISALLOW_UNFILTERED_HTML` set to `true` in `wp-config.php` | Nobody. Use the [shortcode](#shortcode). |
| WordPress.com | Anyone who can edit, but only on a paid plan with hosting features turned on. Hosting features turn on when you install a plugin. On other plans the tags are removed. |

## Custom HTML block

### Step 1: Add the block

In the block editor, type `/html` and choose **Custom HTML**. To put the form on every page, add the block to a template part such as the footer in the Site Editor instead.

### Step 2: Paste the form

`Custom HTML`:

```html
<form class="ikiform" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <p><label>Name <input name="name" autocomplete="name" required></label></p>
  <p><label>Email <input name="email" type="email" autocomplete="email" required></label></p>
  <p><label>Message <textarea name="message" rows="5"></textarea></label></p>
  <input type="hidden" name="_redirect" value="https://example.com/thank-you/">
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
  <p><button type="submit" class="wp-element-button">Send</button></p>
</form>
```

`wp-element-button` gives the button your theme's button style in block themes. The form inherits your theme's fonts and input styles, so it usually needs no CSS.

### Step 3: Preview, then update

Use the block's **Preview** tab, then save. Reload the editor and open the block again: if the `<form>` and `<input>` tags are gone, your account can't save them. Use the shortcode below.

`_redirect` only works when the form has allowed domains that include your site; otherwise visitors see Ikiform's thank-you page. You can also set **Redirect after submit** in the form's settings and drop the hidden input.

## A shortcode

A shortcode keeps the HTML in PHP, where the content filter doesn't touch it, so authors and contributors can place the form too. Save this as a must-use plugin, which WordPress loads automatically:

`wp-content/mu-plugins/ikiform.php`:

```php
<?php

add_shortcode('ikiform', function ($atts) {
    $atts = shortcode_atts([
        'id' => 'frm_xxxxxxxxxxxxxxxx',
        'subject' => '',
        'redirect' => '',
        'button' => 'Send',
    ], $atts, 'ikiform');

    ob_start();
    ?>
    <form class="ikiform" action="<?php echo esc_url('https://ikiform.com/f/' . rawurlencode($atts['id'])); ?>" method="post">
      <p><label>Email <input name="email" type="email" autocomplete="email" required></label></p>
      <p><label>Message <textarea name="message" rows="5"></textarea></label></p>
      <?php if ($atts['subject']) : ?>
        <input type="hidden" name="_subject" value="<?php echo esc_attr($atts['subject']); ?>">
      <?php endif; ?>
      <?php if ($atts['redirect']) : ?>
        <input type="hidden" name="_redirect" value="<?php echo esc_url($atts['redirect']); ?>">
      <?php endif; ?>
      <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
      <p><button type="submit" class="wp-element-button"><?php echo esc_html($atts['button']); ?></button></p>
    </form>
    <?php
    return ob_get_clean();
});
```

Then add a **Shortcode** block, or type the shortcode in any content:

`Shortcode block`:

```text
[ikiform subject="New enquiry" redirect="https://example.com/thank-you/"]
```

- Pass `id` to use another form: `[ikiform id="frm_..."]`.
- Change the fields in the PHP to match your form. Every input with a `name` is stored.
- In the classic editor, paste raw HTML in the **Text** tab only. The visual editor adds `<p>` and `<br>` tags inside the form. The shortcode avoids this.

## Allowed domains

List each address the site answers on. WordPress sites often have several while you build.

| Where the form runs | Add to Allowed domains |
| --- | --- |
| Your live domain | `example.com`, which also covers `www.example.com` |
| WordPress.com address | `your-site.wordpress.com`, or `your-site.wpcomstaging.com` for staging sites |
| Your host's staging site | The staging host from your host's dashboard |
| Local development | `localhost`, or the local host name your tool gives you, such as `my-site.local` |

- Never add `wordpress.com` or `wpcomstaging.com` on its own. Every site on that host would match, including other people's.

## Test checklist

1. Log out, or open a private window. Logged-in admins skip some caches and see a slightly different page.
2. Submit the form and confirm the submission in Ikiform, under received rather than spam.
3. Check you land on your thank-you page. If you see Ikiform's page, the site is missing from allowed domains or the `_redirect` URL isn't `https:`.
4. Edit the page as a non-admin user and confirm the form survives a save, or use the shortcode.

## Troubleshooting

| What you see | Why | Fix |
| --- | --- | --- |
| The form fields vanish after saving, leaving only the labels | Your account lacks `unfiltered_html`, or the WordPress.com plan filters `form` and `input` | Use the shortcode, or have an Administrator paste the block. |
| Stray `<p>` and `<br>` tags break the layout | The classic editor's visual mode reformatted the HTML | Use a Custom HTML block or the shortcode. |
| The browser console says the form data was refused because of the `form-action` directive | A security plugin or your host sends a `Content-Security-Policy` header | Add `https://ikiform.com` to `form-action`, and to `connect-src` if you post with `fetch`. |
| Submissions arrive under the spam filter with `origin_mismatch` | The page that posted isn't on the form's allowed domains | Add the host from the table above. With **Reject** chosen, the same posts get `403 origin_not_allowed` instead. |
| `422 validation_failed` listing an Unknown field | The form has fields defined and an input name isn't one of them | Rename the input to the field id, or start it with `_` if it's only a marker for you. |

## Related

- [HTML forms](https://ikiform.com/docs/html.md): Redirects, reserved fields and the honeypot.
- [Site builders](https://ikiform.com/docs/guides/site-builders.md): The embed that works in any builder.
- [Spam protection](https://ikiform.com/docs/spam.md): Honeypot, scoring and the human check.
- [Troubleshooting](https://ikiform.com/docs/troubleshooting.md): CORS, origin mismatches and 429s.
