Usage

Usage

Usage

Learn how to integrate Formic into your web application.

Quick Start

  1. Get your API key from the Formic dashboard
  2. Create a form in the dashboard and get your form slug
  3. Set up the adapter for your framework
  4. Submit forms from your frontend

Frontend Integration

Simple Form Submission

<form id="my-form">
  <input type="email" name="email" required placeholder="Your email">
  <textarea name="message" required placeholder="Your message"></textarea>
  <button type="submit">Submit</button>
</form>

<script>
document.getElementById('my-form').addEventListener('submit', async (e) => {
  e.preventDefault();
  const formData = new FormData(e.target);
  const data = Object.fromEntries(formData);

  const response = await fetch('/api/submit', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  });

  const result = await response.json();
  console.log(result);
});
</script>

With React/Vue/Svelte

// React example
function ContactForm() {
  const [status, setStatus] = useState('idle');

  const handleSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData(e.target);
    const data = Object.fromEntries(formData);

    setStatus('submitting');
    const res = await fetch('/api/submit', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data)
    });
    const result = await res.json();
    setStatus(result.success ? 'success' : 'error');
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="email" type="email" required />
      <textarea name="message" required />
      <button type="submit" disabled={status === 'submitting'}>
        {status === 'submitting' ? 'Sending...' : 'Send'}
      </button>
    </form>
  );
}

Security Best Practices

When using the Formic client library, follow these security guidelines:

  • Never expose your API key in client-side code — Always use the server-side proxy pattern (see examples below). The API key should only exist in server-side environment variables.
  • Use server-side adapters — The Astro, Next.js, and Remix adapters handle request proxying so the API key stays on your server.
  • Validate payload size client-side — Enable validatePayloadSize: true to catch oversized submissions before they reach the network.
  • Forward Turnstile tokens — Pass Turnstile tokens from your frontend to the Formic API for anti-bot protection.

For a complete guide, see the Security Overview and Authentication documentation.

Server-Side Setup

Astro

// src/pages/api/contact.ts
import { handleFormicRequest } from '@audelabs/formic-client/adapters/astro';

export const POST = handleFormicRequest({
  apiKey: import.meta.env.FORMIC_API_KEY,
  slug: 'contact-form'
});

Next.js (App Router)

// app/api/contact/route.ts
import { handleFormicRequest } from '@audelabs/formic-client/adapters/next';

export const POST = handleFormicRequest({
  apiKey: process.env.FORMIC_API_KEY!,
  slug: 'contact-form'
}).POST;

Remix

// app/routes/contact.tsx
import { handleFormicRequest } from '@audelabs/formic-client/adapters/remix';

export const action = handleFormicRequest({
  apiKey: process.env.FORMIC_API_KEY!,
  slug: 'contact-form'
});

Error Handling

All adapters support error handling via try/catch:

import { createFormicClient } from '@audelabs/formic-client/adapters/next';

export const POST = async (request) => {
  try {
    const client = createFormicClient({
      apiKey: process.env.FORMIC_API_KEY!,
      slug: 'my-form'
    });
    return await client.handleProxyRequest(request);
  } catch (error) {
    return new Response(JSON.stringify({
      error: 'Submission failed',
      message: error instanceof Error ? error.message : 'Unknown error'
    }), { status: 500 });
  }
};

Configuration Options

Custom Base URL

Use a custom API endpoint for development or testing:

const client = new FormicClient({
  apiKey: 'your-api-key',
  slug: 'your-form-slug',
  baseUrl: 'http://localhost:3000' // For local development
});

Hooks

Adapters support before/after hooks:

handleFormicRequest({
  apiKey: process.env.FORMIC_API_KEY!,
  slug: 'my-form',
  beforeRequest: (request) => {
    console.log('Processing form submission...');
  },
  afterResponse: (response) => {
    console.log('Form submitted successfully');
  }
});