Руководство
Контактная форма Vue (без бэкенда)
Vue - клиентский фреймворк, но контактная форма, которую вы доставляете, не нуждается в бэкенде на вашей стороне. Используйте обычный HTML form action в любом Vue-шаблоне, или Vue 3 SFC с <script setup> и fetch для inline-UX успеха/ошибки.
Используйте обычную HTML-форму
API-маршрут не нужен. Форма POST'ит напрямую в Formhook, и вашему фреймворку никогда не приходится касаться отправки.
<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 в Vue
Используйте этот вариант, если хотите состояния успех/ошибка на клиенте без полной перезагрузки страницы.
<!-- src/components/ContactForm.vue -->
<script setup lang="ts">
import { ref } from "vue";
type Status = "idle" | "sending" | "ok" | "error";
const status = ref<Status>("idle");
async function onSubmit(e: Event) {
e.preventDefault();
status.value = "sending";
const form = e.target as HTMLFormElement;
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),
});
status.value = res.ok ? "ok" : "error";
if (res.ok) form.reset();
}
</script>
<template>
<p v-if="status === 'ok'">Thanks - we'll be in touch.</p>
<form v-else @submit="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>
<p v-if="status === 'error'">Something went wrong. Please try again.</p>
</form>
</template>Как это работает
Обычная HTML-форма работает в любом Vue-шаблоне - это просто markup. Для inline-потока успеха/ошибки SFC-сниппет использует <script setup> с state machine статуса на основе ref и вызов fetch к formhook.app/f/YOUR_API_KEY. Object.fromEntries(new FormData(form)), сериализованный в JSON, - самая чистая форма payload'а; Formhook также принимает form-encoded и multipart.
Что происходит дальше
- Отправка попадает в панель Formhook в течение секунды.
- Push-уведомление срабатывает на каждом включённом устройстве.
- Отвечайте прямо из панели (Pro и выше) - особенно полезно для чистых SPA-деплоев без возможности отправки почты.
Запустите вашу контактную форму на Vue сегодня.
Зарегистрируйтесь бесплатно, создайте форму, вставьте API-ключ. Пять минут.
Начать бесплатноБесплатный тариф: 5 форм · 250 отправок/мес · Без банковской карты.
Контактная форма Vue - FAQ
- Нужен ли бэкенд или Node-сервер для этой Vue-формы контактов?
- Нет. Форма POST'ит напрямую в Formhook, так что ваше Vue-приложение может оставаться чистой статической SPA. Соберите Vite, деплойте папку dist/ на любой CDN.
- Можно ли использовать это с состоянием Pinia / Vue Router?
- Да - сниппет - это самодостаточный SFC, но вы можете поднять состояние статуса в Pinia или использовать Vue Router для перехода на отдельный маршрут благодарности после успеха.
- А если я использую Options API вместо <script setup>?
- Тот же паттерн fetch работает в обработчике methods.onSubmit с data() { return { status: 'idle' } }. Меняется только синтаксис - Formhook'у всё равно, какой стиль Vue вы используете.
Руководства для других фреймворков
Migrating from Formspree? See how Formhook compares.