Skip to Content
ExamplesJekyll Integration

Jekyll Integration

Jekyll is a popular static site generator. This guide shows you how to add Kollect forms to your Jekyll site.

Basic Contact Form

Create a contact page:

--- layout: default title: Contact permalink: /contact/ --- <div class="contact-page"> <h1>{{ page.title }}</h1> <form action="https://kollect.app/f/YOUR_FORM_KEY" method="POST" class="contact-form"> <div class="form-group"> <label for="name">Name</label> <input type="text" id="name" name="name" required> </div> <div class="form-group"> <label for="email">Email</label> <input type="email" id="email" name="email" required> </div> <div class="form-group"> <label for="message">Message</label> <textarea id="message" name="message" rows="5" required></textarea> </div> <button type="submit">Send Message</button> </form> </div>

Using Includes

Create a reusable form include:

<!-- _includes/contact-form.html --> <form action="https://kollect.app/f/{{ include.form_key | default: site.kollect.contact_form_key }}" method="POST" class="kollect-form" > <div class="form-group"> <label for="name">{{ include.name_label | default: "Name" }}</label> <input type="text" id="name" name="name" required placeholder="{{ include.name_placeholder }}" > </div> <div class="form-group"> <label for="email">{{ include.email_label | default: "Email" }}</label> <input type="email" id="email" name="email" required placeholder="{{ include.email_placeholder }}" > </div> <div class="form-group"> <label for="message">{{ include.message_label | default: "Message" }}</label> <textarea id="message" name="message" rows="{{ include.rows | default: 5 }}" required placeholder="{{ include.message_placeholder }}" ></textarea> </div> <button type="submit">{{ include.submit_text | default: "Submit" }}</button> </form>

Use in your pages:

{% include contact-form.html form_key="YOUR_FORM_KEY" submit_text="Send Message" name_placeholder="Your name" email_placeholder="your@email.com" %}

Configuration in _config.yml

Store form keys in your Jekyll configuration:

# _config.yml kollect: contact_form_key: "your_contact_form_key" newsletter_form_key: "your_newsletter_form_key" feedback_form_key: "your_feedback_form_key"

Access in templates:

<form action="https://kollect.app/f/{{ site.kollect.contact_form_key }}" method="POST"> <!-- form fields --> </form>

Newsletter Signup Include

<!-- _includes/newsletter.html --> <div class="newsletter-signup"> <h3>{{ include.title | default: "Subscribe to our newsletter" }}</h3> <p>{{ include.description }}</p> <form action="https://kollect.app/f/{{ site.kollect.newsletter_form_key }}" method="POST" class="newsletter-form" > <input type="email" name="email" placeholder="{{ include.placeholder | default: 'Enter your email' }}" required > <button type="submit">{{ include.submit | default: "Subscribe" }}</button> </form> </div>

Use in layouts or pages:

{% include newsletter.html title="Stay Updated" description="Get the latest updates directly to your inbox" placeholder="your@email.com" %}

AJAX Form Submission

Create a JavaScript file for handling AJAX submissions:

// assets/js/form-handler.js (function() { 'use strict'; // Handle all forms with class 'ajax-form' document.querySelectorAll('.ajax-form').forEach(function(form) { form.addEventListener('submit', async function(e) { e.preventDefault(); const submitBtn = form.querySelector('button[type="submit"]'); const originalText = submitBtn.textContent; const formData = new FormData(form); // Update button state submitBtn.disabled = true; submitBtn.textContent = 'Sending...'; try { const response = await fetch(form.action, { method: 'POST', body: formData }); if (response.ok) { showMessage(form, 'success', 'Thank you! Your message has been sent.'); form.reset(); } else { throw new Error('Submission failed'); } } catch (error) { showMessage(form, 'error', 'Oops! Something went wrong. Please try again.'); } finally { submitBtn.disabled = false; submitBtn.textContent = originalText; } }); }); function showMessage(form, type, message) { // Remove existing message const existingMessage = form.querySelector('.form-message'); if (existingMessage) { existingMessage.remove(); } // Create new message const messageDiv = document.createElement('div'); messageDiv.className = `form-message ${type}-message`; messageDiv.textContent = message; form.appendChild(messageDiv); // Auto-remove after 5 seconds setTimeout(() => messageDiv.remove(), 5000); } })();

Include in your layout:

<!-- _layouts/default.html --> <script src="{{ '/assets/js/form-handler.js' | relative_url }}"></script>

Use AJAX forms:

<form action="https://kollect.app/f/{{ site.kollect.contact_form_key }}" method="POST" class="ajax-form" > <!-- form fields --> </form>

Advanced Form with Validation

<!-- _includes/advanced-contact-form.html --> <form action="https://kollect.app/f/{{ site.kollect.contact_form_key }}" method="POST" id="contact-form" class="ajax-form validated-form" > <div class="form-group"> <label for="name">Name <span class="required">*</span></label> <input type="text" id="name" name="name" required minlength="2" data-error="Please enter your name (at least 2 characters)" > <span class="error-message"></span> </div> <div class="form-group"> <label for="email">Email <span class="required">*</span></label> <input type="email" id="email" name="email" required data-error="Please enter a valid email address" > <span class="error-message"></span> </div> <div class="form-group"> <label for="phone">Phone</label> <input type="tel" id="phone" name="phone" pattern="[0-9]{10}" data-error="Please enter a valid 10-digit phone number" > <span class="error-message"></span> </div> <div class="form-group"> <label for="subject">Subject <span class="required">*</span></label> <select id="subject" name="subject" required data-error="Please select a subject"> <option value="">Choose a subject</option> <option value="general">General Inquiry</option> <option value="support">Support</option> <option value="sales">Sales</option> <option value="other">Other</option> </select> <span class="error-message"></span> </div> <div class="form-group"> <label for="message">Message <span class="required">*</span></label> <textarea id="message" name="message" rows="5" required minlength="10" data-error="Please enter a message (at least 10 characters)" ></textarea> <span class="error-message"></span> </div> <button type="submit"> <span class="btn-text">Send Message</span> <span class="btn-loader" style="display: none;">Sending...</span> </button> </form>

File Upload Form

<!-- _includes/file-upload-form.html --> <form action="https://kollect.app/f/{{ site.kollect.upload_form_key }}" method="POST" enctype="multipart/form-data" class="file-upload-form" > <div class="form-group"> <label for="applicant-name">Full Name</label> <input type="text" id="applicant-name" name="name" required> </div> <div class="form-group"> <label for="applicant-email">Email</label> <input type="email" id="applicant-email" name="email" required> </div> <div class="form-group"> <label for="resume">Resume (PDF only)</label> <input type="file" id="resume" name="resume" accept=".pdf" required > <small class="form-text">Maximum file size: 10MB</small> </div> <div class="form-group"> <label for="cover-letter">Cover Letter (Optional)</label> <textarea id="cover-letter" name="coverLetter" rows="5"></textarea> </div> <button type="submit">Submit Application</button> </form>

Liquid-Powered Dynamic Forms

<!-- _includes/dynamic-form.html --> {% assign fields = include.fields | split: "," %} <form action="https://kollect.app/f/{{ include.form_key }}" method="POST" > {% for field in fields %} {% assign field_parts = field | split: ":" %} {% assign field_name = field_parts[0] %} {% assign field_type = field_parts[1] | default: "text" %} <div class="form-group"> <label for="{{ field_name }}">{{ field_name | capitalize }}</label> {% if field_type == "textarea" %} <textarea id="{{ field_name }}" name="{{ field_name }}" rows="5"></textarea> {% else %} <input type="{{ field_type }}" id="{{ field_name }}" name="{{ field_name }}"> {% endif %} </div> {% endfor %} <button type="submit">{{ include.submit | default: "Submit" }}</button> </form>

Use dynamically:

{% include dynamic-form.html form_key="YOUR_FORM_KEY" fields="name:text,email:email,message:textarea" submit="Send" %}

Custom Success Page

Create a thank you page:

--- layout: default title: Thank You permalink: /thank-you/ --- <div class="thank-you-page"> <h1>Thank You!</h1> <p>We've received your message and will get back to you soon.</p> <a href="/" class="btn">Return Home</a> </div>

Add redirect to form:

<form action="https://kollect.app/f/YOUR_FORM_KEY" method="POST"> <input type="hidden" name="_redirect" value="{{ site.url }}/thank-you/"> <!-- form fields --> </form>

Styling with Sass

// _sass/components/_forms.scss .contact-form { max-width: 600px; margin: 0 auto; padding: 2rem; .form-group { margin-bottom: 1.5rem; label { display: block; margin-bottom: 0.5rem; font-weight: 500; color: $text-color; .required { color: $error-color; } } input, textarea, select { width: 100%; padding: 0.75rem; border: 1px solid $border-color; border-radius: 4px; font-size: 1rem; transition: border-color 0.2s; &:focus { outline: none; border-color: $primary-color; box-shadow: 0 0 0 3px rgba($primary-color, 0.1); } &.error { border-color: $error-color; } } .error-message { display: block; color: $error-color; font-size: 0.875rem; margin-top: 0.25rem; min-height: 1.25rem; } .form-text { display: block; color: $muted-color; font-size: 0.875rem; margin-top: 0.25rem; } } button[type="submit"] { padding: 0.75rem 2rem; background: $primary-color; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; transition: background 0.2s; &:hover { background: darken($primary-color, 10%); } &:disabled { background: $disabled-color; cursor: not-allowed; } } .form-message { padding: 1rem; border-radius: 4px; margin-top: 1rem; &.success-message { background: $success-bg; border: 1px solid $success-border; color: $success-text; } &.error-message { background: $error-bg; border: 1px solid $error-border; color: $error-text; } } }

Collection-Based Forms

Generate forms from data:

# _data/contact_forms.yml - name: "General Contact" key: "general_contact_key" fields: - name: "name" type: "text" label: "Name" required: true - name: "email" type: "email" label: "Email" required: true - name: "message" type: "textarea" label: "Message" required: true - name: "Support Request" key: "support_request_key" fields: - name: "ticket_type" type: "select" label: "Issue Type" options: ["Bug", "Feature Request", "Question"] required: true

Create forms from data:

{% for form_config in site.data.contact_forms %} <h2>{{ form_config.name }}</h2> <form action="https://kollect.app/f/{{ form_config.key }}" method="POST"> {% for field in form_config.fields %} <div class="form-group"> <label for="{{ field.name }}">{{ field.label }}</label> {% if field.type == "select" %} <select id="{{ field.name }}" name="{{ field.name }}" {% if field.required %}required{% endif %}> {% for option in field.options %} <option value="{{ option }}">{{ option }}</option> {% endfor %} </select> {% elsif field.type == "textarea" %} <textarea id="{{ field.name }}" name="{{ field.name }}" {% if field.required %}required{% endif %}></textarea> {% else %} <input type="{{ field.type }}" id="{{ field.name }}" name="{{ field.name }}" {% if field.required %}required{% endif %}> {% endif %} </div> {% endfor %} <button type="submit">Submit</button> </form> {% endfor %}

Next Steps

Last updated on