Перейти к содержимому
FFormhook
Все руководства

Руководство

Контактная форма Next.js (без бэкенда)

Next.js не нужен свой приёмник формы. Можно вставить тот же простой HTML-form action в любой Server Component, или - если нужны клиентские состояния успеха и ошибки - использовать небольшой Client Component с fetch. Оба POST'ят напрямую в Formhook.

Используйте обычную HTML-форму

API-маршрут не нужен. Форма POST'ит напрямую в Formhook, и вашему фреймворку никогда не приходится касаться отправки.

contact.html
<form action="https://formhook.app/f/YOUR_API_KEY" method="POST">
  <label>
    Email
    <input type="email" name="email" required />
  </label>

  <label>
    Message
    <textarea name="message" required></textarea>
  </label>

  <!-- honeypot: bots fill this; humans don't see it -->
  <input type="text" name="_gotcha" tabindex="-1" autocomplete="off" hidden />

  <!-- optional: send users to a thank-you page after a native POST -->
  <input type="hidden" name="_redirect" value="https://example.com/thanks" />

  <button type="submit">Send</button>
</form>

Или отправить через fetch в Next.js

Используйте этот вариант, если хотите состояния успех/ошибка на клиенте без полной перезагрузки страницы.

components/contact-form.tsx
"use client";

import { useState } from "react";

export function ContactForm() {
  const [status, setStatus] = useState<"idle" | "sending" | "ok" | "error">("idle");

  async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setStatus("sending");

    const form = e.currentTarget;
    const data = Object.fromEntries(new FormData(form));

    const res = await fetch("https://formhook.app/f/YOUR_API_KEY", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data),
    });

    setStatus(res.ok ? "ok" : "error");
    if (res.ok) form.reset();
  }

  if (status === "ok") return <p>Thanks - we'll be in touch.</p>;

  return (
    <form onSubmit={onSubmit}>
      <input type="email" name="email" placeholder="Email" required />
      <textarea name="message" placeholder="Message" required />
      <input type="text" name="_gotcha" tabIndex={-1} hidden />
      <button type="submit" disabled={status === "sending"}>
        {status === "sending" ? "Sending…" : "Send"}
      </button>
      {status === "error" && <p>Something went wrong. Please try again.</p>}
    </form>
  );
}

Как это работает

Обычный form action работает в любой странице или layout'е Next.js, включая Server Components. Никакого app/api/contact/route.ts, никакого Server Action, никакого middleware. Если хотите клиентский UX с состояниями успеха и ошибки, второй сниппет показывает канонический паттерн: "use client", useState, onSubmit, fetch к formhook.app/f/YOUR_API_KEY. Honeypot (_gotcha) и опциональный _redirect - те же специальные поля из HTML-руководства.

Что происходит дальше

  • Отправка появляется в панели Formhook в течение секунды.
  • Push-уведомление приходит на каждое включённое устройство.
  • Отвечайте прямо из панели (Pro и выше) - удобно для клиентской работы, где у каждого проекта свой маршрут контактов.

Запустите вашу контактную форму на Next.js сегодня.

Зарегистрируйтесь бесплатно, создайте форму, вставьте API-ключ. Пять минут.

Начать бесплатно

Бесплатный тариф: 5 форм · 250 отправок/мес · Без банковской карты.

Контактная форма Next.js - FAQ

Нужно ли добавлять API-маршрут или Server Action?
Нет. Форма POST'ит напрямую в Formhook. Без API-маршрута также одной поверхностью меньше для собственного rate-limit'а и одним cold start'ом меньше на serverless-деплоях.
Можно ли использовать это в Server Component?
Да - сниппет с обычной HTML-формой работает в любом Server Component. Только версия с fetch должна быть Client Component, потому что использует useState.
Как бороться со спамом без написания middleware с rate-limit'ом?
Защита от спама на стороне Formhook. Honeypot тихо отбрасывает ботов, а Cloudflare Turnstile - переключатель на форму в панели. Per-IP и per-form rate limit также применяются на сервере.

Руководства для других фреймворков

Migrating from Formspree? See how Formhook compares.