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

Руководство

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

Remix построен вокруг серверных маршрутов, но контактная форма не обязана быть одним из них. Можно POST'ить напрямую в Formhook из браузера простым form action - или, если хотите progressive enhancement Remix, используйте useFetcher для управления состоянием отправки.

Используйте обычную 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 в Remix

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

app/routes/contact.tsx
// app/routes/contact.tsx
import { useFetcher } from "@remix-run/react";

export default function Contact() {
  const fetcher = useFetcher();
  const status = fetcher.state === "submitting" ? "sending" : fetcher.data?.ok ? "ok" : "idle";

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

  return (
    <fetcher.Form
      method="post"
      action="https://formhook.app/f/YOUR_API_KEY"
      encType="application/x-www-form-urlencoded"
    >
      <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>
    </fetcher.Form>
  );
}

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

Обычный сниппет формы работает как стандартная HTML-форма - <Form> от Remix роутил бы отправку в Remix action, но указание action на formhook.app/f/YOUR_API_KEY полностью обходит Remix и отправляет данные напрямую в Formhook. Версия с useFetcher сохраняет progressive enhancement Remix, но всё равно POST'ит наружу: браузер делает XHR-отправку, а вы получаете fetcher.state для управления UI.

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

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

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

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

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

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

Контактная форма Remix - FAQ

Нужно ли писать функцию-action Remix?
Нет. Указание form action на formhook.app полностью обходит роутинг Remix. Если предпочитаете проксировать через Remix action для логирования или формирования payload'а - можете, но это не обязательно.
Будет ли useFetcher работать, если action на другом origin?
Да. useFetcher под капотом использует fetch, так что cross-origin запросы работают при условии, что список разрешённых origins вашей формы Formhook включает origin вашего приложения Remix.
Работает ли это с `unstable_singleFetch` Remix или React Router 7?
Да - отправка формы идёт напрямую в Formhook, так что изменения в загрузке данных или роутинге Remix её не затрагивают.

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

Migrating from Formspree? See how Formhook compares.