Блог

Почему форма не переносится с Craftum и mottor

16 июля 2026 г.·9 мин чтения·Марк

Если форма не переносится с Craftum или mottor — это не сбой скачивания. Дело в том, что формы в HTML этих конструкторов не существует. Совсем. Откройте исходный код страницы (Ctrl+U) и поищите тег <form> — вы его не найдёте, хотя на экране форма прекрасно видна.

Это не редкость и не баг конструктора: так устроены Craftum, mottor и ещё несколько платформ. Разберём, что там на самом деле и почему из-за этого простое скачивание сайта даёт страницу без формы.

Попробуйте перенос бесплатно

Одна страница — бесплатно. Оцените результат за 1 минуту.

Перенести сайт

Что реально лежит в HTML

Браузер показывает форму, потому что её рисует JavaScript уже после загрузки страницы. В исходном коде вместо формы лежат:

  • несколько <input>, ни во что не обёрнутых — они болтаются сами по себе;
  • красиво оформленная кнопка, которая почти никогда не является <button type="submit"> — обычно это <a> или <div> с нужными классами;
  • скрипт, который в момент открытия страницы всё это собирает в рабочую форму и вешает отправку на серверы конструктора.

Три следствия, и все неприятные:

  1. wget и подобные утилиты забирают HTML до того, как отработал JavaScript. Они получают сироток-инпутов без формы. На скачанной странице поля видны, а отправлять нечего и некуда.
  2. Даже если форма отрисуется, она отправляет данные на серверы конструктора. А те принимают заявки только с оплаченного сайта на своём домене — с чужого хостинга запрос просто не пройдёт.
  3. Кнопка не умеет отправлять. <div> не отправляет форму по своей природе; за это отвечал скрипт, которого больше нет.

Как это чинится

Шаг 1: отрисовать страницу по-настоящему

Скачивать нужно не исходный HTML, а тот, что получается после работы JavaScript. Мы открываем страницу в настоящем браузере (Playwright), дожидаемся появления полей ввода и только тогда снимаем разметку. На этом этапе форма уже существует как DOM.

Важная деталь: ждать нужно именно нужного элемента, а не «пять секунд на всякий случай». Для Craftum и mottor мы ждём появления input — если ждать по таймеру, на медленном соединении снимок уйдёт раньше, чем форма отрисуется.

Шаг 2: обернуть сироток в настоящую форму

Дальше находим поля, которые остались без родителя, и оборачиваем их в честный <form> с адресом обработчика. Здесь есть тонкость, на которой мы один раз обожглись: определять кнопку по классу нужно аккуратно.

Кнопки Craftum — это .btn-new и .btn-new2. Наивная проверка «класс начинается с btn-new» цепляет заодно btn-new3 и btn-new99, которых в вёрстке может быть сколько угодно. У mottor похожая ловушка: m-button — это кнопка, а m-buttons — обёртка вокруг неё. Промахнёшься на одну букву — и обработчик повесится на контейнер, а не на кнопку. Теперь классы сверяются по границам, а не по «начинается с».

Шаг 3: заставить кнопку отправлять по-настоящему

Кнопку-<div> мы превращаем в отправляющую. И тут — самое неочевидное место всей истории.

Казалось бы, по клику надо вызвать form.submit(). Так делать нельзя. Нативный form.submit() не порождает событие submit — он молча уходит на сервер в обход всех обработчиков. А значит, в обход нашего перехватчика, который отправляет заявку по-тихому и показывает «спасибо». Результат: посетитель нажимает «Отправить» и видит голый JSON вместо благодарности.

Правильно — попросить браузер отправить форму так, как будто нажали настоящую кнопку: requestSubmit() (или отправленное вручную отменяемое событие). Тогда событие submit возникает, перехватчик его ловит, и человек видит нормальное подтверждение.

Шаг 4: принять заявку

Вместе с сайтом мы кладём form-handler.php — маленький PHP-скрипт, который принимает поля и отправляет их вам на почту (и в Telegram, если настроите). Ему нужен только PHP — он есть на любом обычном хостинге: Beget, Timeweb, REG.RU, SprintHost. Подобрать площадку поможет рейтинг хостингов.

Подтверждение показываем только после реального ответа сервера, а не сразу по клику. Оптимистичное «спасибо, заявка отправлена» с последующей тишиной — худшее, что можно сделать с формой заявок.

Почему у Тильды иначе

У Тильды <form> в HTML есть — там задача проще: подменить адрес отправки на свой обработчик, и всё. Именно поэтому «перенёс с Тильды — формы заработали, перенёс с Craftum — форм нет» выглядит загадкой, хотя разница вся в том, кто рисует форму: сервер или браузер.

Это же объясняет, почему нельзя написать один парсер «для конструкторов вообще». Каждая платформа ломается по-своему, и правило, написанное под одну, ничего не знает про другую — поэтому каждый конструктор мы разбираем отдельно.

Часто задаваемые вопросы

Почему в скачанном сайте нет формы, хотя на сайте она есть?

Потому что Craftum и mottor рисуют форму скриптом уже в браузере. В исходном HTML её нет — есть отдельные поля и оформленная кнопка. Утилиты вроде wget забирают HTML до работы скрипта и формы не видят.

Заработает ли форма после переноса?

Да, но не сама по себе. Нужно, чтобы форму собрали заново и подключили к обработчику. Webrelay делает это автоматически: отрисовывает страницу в браузере, оборачивает поля в <form> и кладёт рядом form-handler.php. От вас — указать почту для заявок.

Нужен ли для формы PHP-хостинг?

Для готового form-handler.php — да. Подойдёт любой обычный хостинг. На бесплатных площадках вроде Netlify, Vercel и Cloudflare PHP не выполняется: там форму надо переводить на их собственные функции или на сервис вроде Formspree.

Почему форма отправляется, но вместо «спасибо» показывается JSON?

Классический признак того, что кнопку заставили вызвать form.submit() напрямую. Такой вызов не порождает событие submit и проходит мимо перехватчика, который должен был показать подтверждение. Лечится отправкой через requestSubmit().

Придут ли старые заявки, которые лежат в конструкторе?

Нет, это архив внутри платформы. Выгрузите их до переноса — после отключения тарифа доступ пропадёт.

Что ещё не переносится вместе с сайтом?

Корзина превращается в заявку: у статического сайта нет серверной части, поэтому онлайн-оплата картой не работает. Подробнее — в статье почему на статическом сайте не работает оплата. Общий список — что переносится с конструктора.

Читайте также