Uniform contact plugin

Today I tried the uniform plugin.
Everything works as expected except one thing.
Each time I reload the page, the form content is being sent again. How can I prevent this?


use Uniform\Form;

return function ($kirby)
  $form = new Form([
    'name' => [
      'rules' => ['required', 'min' => 3],
      'message' => 'Please enter name',
    'email' => [
      'rules' => ['required', 'email'],
      'message' => 'Please enter email address',
    'select' => [
      'rules' => ['required', 'in' => [['option1', 'option2', 'option3']]],
      'message' => 'Please select an option',
    'message' => [
      'rules' => ['required', 'min' => 10],
      'message' => 'Please enter a message',

  if ($kirby->request()->is('post')) {
      'to' => 'email@domain.tld',
      'from' => 'email@domain.tld',
      //'template' => 'html',
      //'template' => 'email',

  return compact('form');

template snippet:

<style type="text/css">
    label, input, textarea {
        display: block;
    .uniform__potty {
        position: absolute;
        left: -9999px;
    .error {
        border-bottom: 1px solid red;

<div class="fl cs12">
  <div class="mwx1500 center bg-ffffff pas32">
    <h1 class="tac">Contact Form</h1>
  <div class="mwx1500 center bg-ffffff phs32">
  <?php if ($form->success()): ?>
    <h2>Thank you for your message. We will get back to you soon!</h2>
  <?php else: ?>
    <?php snippet('uniform/errors', ['form' => $form]) ?>
  <?php endif; ?>
  <form action="<?php echo $page->url() ?>" method="post">
    <div class="form-group">
      <label class="form-label" for="name">Name</label>
      <input class="form-input<?php if ($form->error('name')): ?> error<?php endif; ?>" id="name" name="name" type="text" value="<?php echo $form->old('name') ?>" placeholder="Name">
    <div class="form-group">
      <label class="form-label" for="email">Email</label>
      <input class="form-input<?php if ($form->error('email')): ?> error<?php endif; ?>" id="email" name="email" type="email" value="<?php echo $form->old('email') ?>" placeholder="Email">
    <div class="form-group">
      <label class="form-label" for="select">Select</label>
      <?php $value = $form->old('select') ?>
      <select class="form-select<?php if ($form->error('select')): ?> error<?php endif; ?>" id="select" name="select">
        <option value="none">Select Option</option>
        <option value="option1"<?php e($value=='option1', ' selected')?>>First</option>
        <option value="option2"<?php e($value=='option2', ' selected')?>>Second</option>
        <option value="option3"<?php e($value=='option3', ' selected')?>>Third</option>
    <div class="form-group">
      <label class="form-label" for="message">Message</label>
      <textarea class="form-input<?php if ($form->error('message')): ?> error<?php endif; ?>" id="message" name="message" placeholder="Message" rows="3"><?php echo $form->old('message') ?></textarea>
    <div class="form-group">
    <?php echo csrf_field() ?>
    <?php echo honeypot_field() ?>
    <input type="submit" value="Submit">

Is this a session thing? i’m using plainkit-3.2.2 for testing.

I’ld suggest to implement the Post/Redirect/Get Pattern.

When a web form is submitted to a server through an HTTP POST request, a web user that attempts to refresh the server response in certain user agents can cause the contents of the original POST request to be resubmitted, possibly causing undesired results, such as a duplicate web purchase.

There is a plugin which helps to solve this issue: https://github.com/mzur/kirby-form

thank you for the hint. but i have no clue how to make this work.
so i decided to do it this way.

if everything went smooth i put the success message into a session and reload the page.

if ($form->success()) {
  $kirby->session()->set([ 'success' => 'Your message has been sent, thank you. We will get back to you soon!' ]);

then i display the success message and delete the session.

  <?php $session = kirby()->session(); ?>
  <h1><?= $session->get('success') ?><?php $session->remove('success') ?></h1>

sounds complicated but works.

1 Like

This plugin is actually part of the Uniform plugin! Do not install twice.

1 Like

@texnixe Good to know! Thanks.