иконка discount

Скидка 15% по промокоду

кибер понедельник до 01.12иконка discount
CYBER2025
логотип PurpleSchool
логотип PurpleSchool

Атрибут action в HTML - как правильно задавать адрес отправки формы

Автор

Олег Марков

Введение

Атрибут action в HTML-форме задает адрес, на который будут отправлены данные пользователя после нажатия кнопки отправки. Как только вы начинаете работать с формами, вам приходится отвечать на вопрос – куда именно уйдут введенные данные и как браузер будет их отправлять. Именно за это отвечает action.

Если атрибут указан неправильно или не указан вовсе, форма может не дойти до нужного обработчика, а сервер — не получить данные в ожидаемом формате и по ожидаемому адресу. В результате вы видите 404, пустые запросы или странное поведение, которое сложно отлаживать.

Давайте разберем, как работает атрибут action, чем отличаются относительные и абсолютные адреса, как он взаимодействует с методами GET и POST, что происходит при пустом или отсутствующем значении, и какие практики помогают избежать проблем в реальных проектах.

Что такое атрибут action в форме

Базовое определение

Атрибут action указывается внутри тега <form> и задает URL-адрес обработчика, куда будут отправлены данные формы.

Простейший пример:

<form action="/submit" method="post">
  <!-- Поля формы -->
  <input type="text" name="username">
  <button type="submit">Отправить</button>
</form>

Комментарии к коду:

<form action="/submit" method="post">
  <!-- action="/submit" - относительный путь до обработчика на сервере -->
  <!-- method="post" - данные отправляются в теле HTTP-запроса -->

  <input type="text" name="username">
  <!-- name="username" - имя параметра, которое сервер увидит в запросе -->

  <button type="submit">Отправить</button>
  <!-- type="submit" - кнопка отправки формы -->
</form>

Как только вы нажимаете кнопку submit, браузер:

  1. Формирует HTTP-запрос.
  2. Использует метод, указанный в method (по умолчанию GET).
  3. Берет адрес из action.
  4. Отправляет данные по этому адресу.

Если атрибут action не указан, используются особые правила, о которых поговорим ниже.

Где можно использовать атрибут action

Атрибут action используется только в теге <form>:

<form action="https://example.com/api/feedback">
  <!-- Поля формы -->
</form>

Попытка указать action в других тегах (например, <button action="...">) не имеет смысла — браузер его просто проигнорирует.

Синтаксис и варианты записи action

Общий синтаксис тега form с action

Базовый вид:

<form action="URL" method="GET или POST" enctype="тип_кодирования">
  <!-- элементы формы -->
</form>

Именно в action="URL" вы задаете маршрут, куда должна уйти форма. URL в этом атрибуте может быть:

  • абсолютным;
  • относительным;
  • пустым (пара вариантов);
  • с query-параметрами;
  • с якорем (фрагментом).

Смотрите, я покажу вам разные варианты и их поведение.

Абсолютный URL в action

Абсолютный URL — это полный адрес с протоколом и доменом:

<form action="https://example.com/form/submit" method="post">
  <!-- поля формы -->
</form>

Комментарии:

<form action="https://example.com/form/submit" method="post">
  <!-- Полный путь до обработчика -->
  <!-- Можно отправлять данные на другой домен (пример - сторонний сервис оплаты) -->
</form>

Особенности:

  • Форма может отправляться на другой домен, поддомен или даже другой протокол (https → http и наоборот).
  • Браузер отправляет запрос по точно заданному адресу, независимо от того, на какой странице находится форма.
  • Вступают в игру ограничения CORS и настройки сервера получателя, но для клиента главное — формирование правильного запроса.

Это часто используется для интеграции с платежными системами, формами внешних сервисов подписки и т.д.

Относительный URL в action

Относительный URL задается без домена. Он интерпретируется относительно текущей страницы.

Пример относительного пути от корня сайта

<form action="/login" method="post">
  <!-- поля формы -->
</form>

Комментарии:

<form action="/login" method="post">
  <!-- /login - путь от корня сайта -->
  <!-- Если сайт https://mysite.com, запрос пойдет на https://mysite.com/login -->
</form>

Пример относительного пути относительно текущего каталога

<form action="submit.php" method="post">
  <!-- поля формы -->
</form>

Комментарии:

<form action="submit.php" method="post">
  <!-- submit.php - путь относительно текущей директории -->
  <!-- Если форма на https://mysite.com/forms/index.html -->
  <!-- Запрос пойдет на https://mysite.com/forms/submit.php -->
</form>

Пример использования .. в пути

<form action="../api/send" method="post">
  <!-- поля формы -->
</form>

Комментарии:

<form action="../api/send" method="post">
  <!-- .. - подняться на один уровень выше по структуре папок -->
  <!-- Если страница https://mysite.com/forms/auth/login.html -->
  <!-- Запрос пойдет на https://mysite.com/forms/api/send -->
</form>

Относительные пути удобны тем, что их проще переносить между стендами (dev, test, prod), не меняя домен в коде.

Action с query-параметрами

Иногда вам нужно передать какие-то фиксированные параметры в URL еще до отправки формы.

<form action="/search?source=form" method="get">
  <input type="text" name="q">
  <button type="submit">Искать</button>
</form>

Комментарии:

<form action="/search?source=form" method="get">
  <!-- В action уже есть параметр source=form -->
  <!-- При отправке добавится параметр q из поля ввода -->
  <!-- Итоговый URL может быть /search?source=form&q=значение -->
</form>

Браузер аккуратно объединяет параметры из action и параметры формы. Если имена совпадают, поведение зависит от реализации, но чаще всего новый параметр добавляется еще одним значением:

/search?source=form&source=other

Поэтому желательно не дублировать имена query-параметров между action и полями формы.

Action с якорем (фрагментом)

Вы можете указать фрагмент (часть после #) в action:

<form action="/profile#contacts" method="post">
  <!-- поля формы -->
</form>

Комментарии:

<form action="/profile#contacts" method="post">
  <!-- #contacts - якорь (фрагмент) на странице профиля -->
  <!-- Сервер его не получит - фрагмент не посылается в HTTP-запросе -->
  <!-- Но после ответа браузер прокрутит страницу к элементу с id="contacts" -->
</form>

С точки зрения HTTP-запроса фрагмент игнорируется. Это чисто клиентская часть, которая используется для навигации на странице.

Что происходит, если action не указан или пустой

Нет атрибута action вообще

Если вы не указали action вообще:

<form method="post">
  <!-- поля формы -->
</form>

Браузер отправит форму на тот же URL, где сейчас находится страница. То есть адрес обработчика будет совпадать с адресом текущего документа.

Например, если форма размещена по адресу:

https://mysite.com/account/settings

то запрос уйдет на:

https://mysite.com/account/settings

На практике такой подход часто используют в простых сценариях, когда одна и та же страница отображает форму и обрабатывает ее отправку.

Пустой атрибут action

Есть несколько похожих, но технически разных случаев:

  1. action не указан: html <form method="post">...</form>
  2. action указан, но пустой: html <form action="" method="post">...</form>
  3. action равен "#": html <form action="#" method="post">...</form>

Разберемся, что делает каждый вариант.

action не указан или равен пустой строке

Поведение этих двух вариантов в современных браузерах практически совпадает: форма отправляется на текущий URL без изменений.

Но есть важный нюанс: взаимодействие с base и особенностями некоторых старых браузеров. В актуальных проектах чаще ориентируются на следующее:

  • <form method="post"> и <form action="" method="post"> отправят запрос на текущий адрес страницы (без добавления # или других фрагментов).
  • Это удобно, если страница сама принимает и обрабатывает отправку.

action="#"

Этот вариант часто используют, когда хотят предотвратить фактическую навигацию, но с формами это не лучший стиль:

<form action="#" onsubmit="sendFormWithAjax(event)">
  <!-- поля формы -->
</form>

Комментарии:

<form action="#" onsubmit="sendFormWithAjax(event)">
  <!-- action="#" - по умолчанию браузер добавит # к текущему URL -->
  <!-- onsubmit - JS-обработчик, который отменит стандартную отправку и отправит данные через AJAX -->
</form>

Если вы не отмените стандартное поведение в JavaScript, страница «скакнет» к началу (из-за добавления # к URL) или перезагрузится, что обычно лишнее.

В большинстве случаев, когда вы отправляете форму через JavaScript, лучше использовать:

<form onsubmit="sendFormWithAjax(event)">
  <!-- поля -->
</form>

и оставить action пустым или не указывать его вовсе, а в JS явно управлять запросом.

Взаимодействие action и method

Атрибут action сам по себе не определяет, как именно передаются данные — только куда. За способ отвечает атрибут method.

Чаще всего используются два метода: GET и POST.

Action с методом GET

Если вы не укажете method, по умолчанию форма отправляется методом GET:

<form action="/search">
  <input type="text" name="q">
  <button type="submit">Поиск</button>
</form>

Комментарии:

<form action="/search">
  <!-- method не указан - используется метод GET по умолчанию -->
  <!-- Параметр q попадет в query-строку URL -->
  <!-- Пример итогового URL: /search?q=текст+запроса -->
</form>

Схема работы:

  1. Браузер берет action, например /search.
  2. Формирует query-строку из значений полей с атрибутом name.
  3. Приклеивает ее к URL.
  4. Отправляет запрос.

Здесь важно понимать: action становится основой URL, а поля формы — параметрами.

Пример с уже заданными параметрами в action

<form action="/search?source=header" method="get">
  <input type="text" name="q">
  <select name="category">
    <option value="all">Все</option>
    <option value="books">Книги</option>
  </select>
  <button type="submit">Искать</button>
</form>

Комментарии:

<form action="/search?source=header" method="get">
  <!-- В action уже есть параметр source=header -->
  <!-- Браузер добавит к нему q и category -->
  <!-- Итог может быть таким: /search?source=header&q=go&category=books -->
</form>

Данные, добавленные через action, и данные из формы соединяются в одну строку запроса.

Action с методом POST

При методе POST данные отправляются в теле HTTP-запроса, а не в URL:

<form action="/login" method="post">
  <input type="text" name="username">
  <input type="password" name="password">
  <button type="submit">Войти</button>
</form>

Комментарии:

<form action="/login" method="post">
  <!-- action="/login" - адрес для POST-запроса -->
  <!-- Данные username и password будут в теле запроса, а не в URL -->
</form>

В этом случае:

  • URL остается /login.
  • Параметры формируются и кодируются согласно enctype (по умолчанию application/x-www-form-urlencoded).
  • Сервер читает их из тела запроса.

action по-прежнему определяет только адрес, а не способ передачи.

Связка action, method и enctype (для файлов)

Если вы отправляете файлы, нужно использовать:

<form action="/upload" method="post" enctype="multipart/form-data">
  <input type="file" name="file">
  <button type="submit">Загрузить</button>
</form>

Комментарии:

<form action="/upload" method="post" enctype="multipart/form-data">
  <!-- multipart/form-data - специальный формат для передачи файлов -->
  <!-- action="/upload" - серверный маршрут, который примет файл -->
</form>

Здесь action определяет URL, а enctype — формат структуры тела запроса.

Отправка формы на другой домен

Иногда форму нужно отправить на внешний сервис: платежный шлюз, CRM, почтовый сервис.

<form action="https://payments.example-pay.com/init" method="post">
  <input type="hidden" name="amount" value="1000">
  <input type="hidden" name="currency" value="RUB">
  <button type="submit">Оплатить</button>
</form>

Комментарии:

<form action="https://payments.example-pay.com/init" method="post">
  <!-- Браузер отправит POST-запрос на другой домен -->
  <!-- После обработки сервер обычно перенаправит пользователя дальше -->
</form>

Что важно учитывать:

  • CORS не мешает обычным отправкам формы (без AJAX). Ограничения CORS действуют для XMLHttpRequest и fetch, но не для формы с обычной отправкой.
  • Сервер-обработчик должен корректно принимать запрос с вашего сайта.
  • Пользователь фактически переходит на другой сайт (если сервер не вернет ответ в виде HTML, который встроен в ваш контекст).

Если вы хотите отправить данные «втихую» и остаться на текущем сайте, обычно используют AJAX (fetch, XMLHttpRequest), а action либо не используют вообще, либо оставляют для «запасного» сценария.

Применение action с различными target

Атрибут target у формы говорит браузеру, куда именно открыть результат отправки.

Открытие результата в новой вкладке

<form action="/report" method="get" target="_blank">
  <input type="text" name="id">
  <button type="submit">Открыть отчет</button>
</form>

Комментарии:

<form action="/report" method="get" target="_blank">
  <!-- target="_blank" - открыть результат в новой вкладке -->
  <!-- Удобно для формирования PDF, отчетов, скачивания файлов -->
</form>

В этом случае:

  • action по-прежнему определяет URL.
  • target определяет контекст отображения результата.

Отправка формы в iframe

<iframe name="resultFrame"></iframe>

<form action="/preview" method="post" target="resultFrame">
  <textarea name="content"></textarea>
  <button type="submit">Предпросмотр</button>
</form>

Комментарии:

<iframe name="resultFrame"></iframe>
<!-- name="resultFrame" - имя, по которому форма найдет этот iframe -->

<form action="/preview" method="post" target="resultFrame">
  <!-- target="resultFrame" - ответ сервера будет показан внутри iframe -->
</form>

Здесь action определяет путь, а target — окно или фрейм, в котором будет показан результат.

Типичные ошибки при использовании action

Ошибка 1 — неправильный относительный путь

Представьте структуру:

/ (корень)
  /forms
    contact.html
    send.php

Форма в contact.html:

<form action="/forms/send.php" method="post">
  <!-- поля -->
</form>

Комментарии:

<form action="/forms/send.php" method="post">
  <!-- Путь начинается с / - значит, он берется от корня сайта -->
  <!-- Это правильно - запрос пойдет на /forms/send.php -->
</form>

Ошибка часто возникает, когда пишут:

<form action="forms/send.php" method="post">
  <!-- часто ожидают путь от корня, но это относительный от текущей папки -->
</form>

Если contact.html лежит в /forms/, то forms/send.php превратится в /forms/forms/send.php, и сервер вернет 404.

Рекомендация: если вам нужен путь от корня сайта, начинайте его с /.

Ошибка 2 — забыли указать action

Часто разработчик рассчитывает, что форма уйдет на конкретный обработчик, но забывает указать action:

<form method="post">
  <!-- поля -->
</form>

В итоге запрос уходит на текущую страницу, а разработчик ищет проблему в серверном коде. Всегда проверяйте, совпадает ли ожидаемый URL с тем, что реально запрашивает браузер (это можно увидеть в сетевых запросах DevTools).

Ошибка 3 — использование action="#" без отмены отправки

Код:

<form action="#" method="post">
  <!-- поля -->
  <button type="submit">Сохранить</button>
</form>

Если вы предполагали обработку формы через JavaScript, но не отменили стандартное поведение, страница будет перезагружаться, а к URL добавится #. Это часто воспринимают как «непонятный баг».

Лучше:

<form onsubmit="handleSubmit(event)">
  <!-- поля -->
</form>

<script>
  function handleSubmit(event) {
    event.preventDefault(); // Здесь мы отменяем стандартную отправку формы
    // Здесь вы реализуете отправку через fetch или другой способ
  }
</script>

Ошибка 4 — неверная комбинация action и method

Например, для формы логина используют GET:

<form action="/login" method="get">
  <input type="text" name="username">
  <input type="password" name="password">
  <button type="submit">Войти</button>
</form>

Комментарии:

<form action="/login" method="get">
  <!-- Данные пойдут в URL, пароль будет виден в адресной строке -->
  <!-- Это плохая практика с точки зрения безопасности -->
</form>

Формально с точки зрения HTML это не ошибка, но с точки зрения безопасности — очень нежелательно. Для таких сценариев нужен method="post".

Атрибут action здесь не виноват, но сочетание action + method должно быть осознанным.

Практические примеры использования action

Пример 1. Обработка на той же странице

Давайте разберемся на простом примере.

<!-- index.php -->
<form method="post">
  <input type="text" name="message">
  <button type="submit">Отправить</button>
</form>

<?php
// Здесь мы обрабатываем данные формы
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Получаем значение поля message
    $message = $_POST['message'] ?? '';
    echo "<p>Вы отправили: " . htmlspecialchars($message) . "</p>";
}
?>

Комментарии:

// action не указан - форма отправится на этот же URL (index.php)
// Сервер проверяет метод запроса
// Если это POST - обрабатывает данные и выводит результат на той же странице

Такой подход часто используют в небольших проектах и при создании простых форм обратной связи.

Пример 2. Разделение страницы формы и обработчика

Теперь давайте посмотрим, как форма может отправлять данные на отдельный обработчик.

<!-- form.html -->
<form action="/handlers/feedback.php" method="post">
  <input type="email" name="email" placeholder="Ваш email">
  <textarea name="message" placeholder="Сообщение"></textarea>
  <button type="submit">Отправить</button>
</form>
<!-- handlers/feedback.php -->
<?php
// Здесь мы принимаем данные от формы
$email = $_POST['email'] ?? '';
$message = $_POST['message'] ?? '';

// Здесь вы можете сохранить данные в БД или отправить письмо

echo "Спасибо, ваше сообщение отправлено";
?>

Комментарии:

// action="/handlers/feedback.php" - форма отправляет запрос на этот скрипт
// Текущая страница (form.html) только показывает форму и не обрабатывает отправку

Здесь action используется для маршрутизации на отдельный обработчик.

Пример 3. Поиск с параметрами (GET + action с query)

Теперь давайте перейдем к примерy с поиском и предзаданными параметрами.

<form action="/search?source=sidebar" method="get">
  <input type="text" name="q" placeholder="Поиск по сайту">
  <select name="type">
    <option value="articles">Статьи</option>
    <option value="products">Товары</option>
  </select>
  <button type="submit">Искать</button>
</form>

Комментарии:

<form action="/search?source=sidebar" method="get">
  <!-- source=sidebar - фиксированный параметр, чтобы сервер знал откуда пришел запрос -->
  <!-- q и type добавятся к URL при отправке -->
</form>

После отправки итоговый URL может выглядеть так:

/search?source=sidebar&q=html+action&type=articles

Сервер может использовать параметр source, чтобы, например, статистически различать запросы из шапки, подвала или боковой панели.

Пример 4. Отправка в iframe для предпросмотра

Покажу вам, как это реализовано на практике с предпросмотром:

<iframe name="previewFrame" style="width:100%; height:200px; border:1px solid #ccc;"></iframe>

<form action="/preview" method="post" target="previewFrame">
  <textarea name="content" rows="5" cols="40" placeholder="Введите текст для предпросмотра"></textarea>
  <button type="submit">Показать предпросмотр</button>
</form>

Комментарии:

<iframe name="previewFrame" style="width:100%; height:200px; border:1px solid #ccc;"></iframe>
<!-- Здесь будет отображаться ответ сервера -->

<form action="/preview" method="post" target="previewFrame">
  <!-- target="previewFrame" - результат отправки откроется в iframe -->
</form>

Сервер по адресу /preview может отдавать HTML-код, сформированный на основе поля content. Это позволяет организовать живой предпросмотр без отдельной JS-логики.

Рекомендации по выбору значения action

Когда указывать абсолютный URL

Используйте абсолютный URL, если:

  • форма отправляет данные на внешний сервис (платежи, интеграции);
  • у проекта сложная конфигурация доменов (поддомены, несколько основных доменов);
  • вы хотите явно зафиксировать конечный адрес, независимый от текущего домена.

Когда лучше использовать относительный URL

Относительные пути удобны:

  • для внутренних обработчиков в одном приложении;
  • при разработке, когда проект переносится между dev/stage/prod средами;
  • когда структура каталогов стабильно определена.

Рекомендация: если это внутренняя обработка в рамках одного сайта — почти всегда достаточно относительного пути, начинающегося с /.

Когда можно не указывать action

Можно опустить action, если:

  • страница сама обрабатывает отправку формы (PHP, Node, Python и т.д.);
  • вы заведомо точно знаете, что текущий URL всегда будет URL обработчика;
  • вы используете JavaScript для отправки (fetch / AJAX), но хотите иметь простой «запасной» сценарий отправки на ту же страницу.

Если логика сложная или URL может меняться, лучше указать action явно, чтобы избежать скрытых зависимостей.


Атрибут action в HTML — это простой по синтаксису, но критически важный элемент формы. Он определяет маршрут, по которому пойдут данные, и напрямую влияет на то, сможет ли сервер получить и обработать их правильно.

Вы рассмотрели:

  • что такое action и как он работает;
  • разницу между абсолютными и относительными URL;
  • что происходит, если action пустой или отсутствует;
  • как action взаимодействует с методами GET и POST;
  • зачем использовать якори, query-параметры и target;
  • типичные ошибки и их последствия;
  • реальные примеры — отправка на ту же страницу, на отдельный обработчик, на внешний сервис, в iframe.

Понимание того, как именно формируется конечный URL запроса формы, помогает быстро отлаживать проблемы и строить предсказуемое поведение пользовательских интерфейсов.

Частозадаваемые технические вопросы по теме и ответы

Почему при отправке формы с action="/path" запрос идет не туда, куда я ожидал

Проверьте, откуда начинается путь. Если путь в action начинается с /, он считается от корня домена. Если без /, он считается относительно текущей директории. Откройте DevTools → Network и посмотрите точный URL запроса, затем сравните его со структурой файлов и маршрутами на сервере. При необходимости начните путь с / или скорректируйте относительный путь.

Как добавить динамический параметр в action с помощью JavaScript перед отправкой формы

Можно изменить form.action в обработчике события submit:

<form id="userForm" action="/user" method="get">
  <input type="text" name="id" id="userId">
</form>

<script>
  document.getElementById('userForm').addEventListener('submit', function (e) {
    const id = document.getElementById('userId').value;
    // Здесь мы динамически дополняем action
    this.action = '/user/' + encodeURIComponent(id);
  });
</script>

Так вы сможете формировать REST-подобные URL прямо перед отправкой.

Как использовать action, если сервер ожидает разные URL для GET и POST

Создайте две отдельные формы с разными action и method, либо динамически меняйте action и method в зависимости от действий пользователя:

<form id="dataForm" action="/data/get" method="get">
  <!-- поля -->
  <button type="button" onclick="sendGet()">GET</button>
  <button type="button" onclick="sendPost()">POST</button>
</form>

<script>
  function sendGet() {
    const form = document.getElementById('dataForm');
    form.action = '/data/get';
    form.method = 'get';
    form.submit();
  }

  function sendPost() {
    const form = document.getElementById('dataForm');
    form.action = '/data/post';
    form.method = 'post';
    form.submit();
  }
</script>

Почему при использовании base href мое значение action ведет на неожиданный URL

Тег <base href="..."> меняет базовый URL для всех относительных ссылок и форм. Если в документе есть <base>, относительный action="submit.php" будет считаться не от URL страницы, а от того, что указано в href. Решения — либо использовать в action путь, начинающийся с /, либо убрать/скорректировать <base>.

Можно ли указывать относительный action в документах, загруженных через file

При открытии файлов напрямую через file:/// относительные пути в action будут строиться относительно файловой системы, а не домена. Браузер при этом может блокировать отправку в некоторых сценариях. Для корректной работы форм лучше запускать страницу через локальный веб-сервер, чтобы URL был вида http://localhost/..., и тогда относительные пути в action будут работать так же, как на реальном сервере.

Стрелочка влевоГруппа полей HTML fieldset

Постройте личный план изучения Html до уровня Middle — бесплатно!

Html — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Все гайды по Html

Тег section в HTML - семантическая разметка структуры страницыТег nav в HTML - полное руководство по семантической навигацииТег main в HTML - подробное руководство по использованиюТег header в HTML - полное практическое руководствоТег footer в HTML - назначение семантика и практические примерыТег figure в HTML - как правильно оформлять иллюстрации и подписиТег figcaption в HTML - подробное руководство с примерамиТег aside в HTML - назначение правильная семантика и примеры
Текстовая область HTML textarea - практическое руководствоВыпадающий список HTML select - полное руководство для разработчиковОпция списка HTML option - как работает и как правильно использоватьАтрибут method в HTML - как правильно отправлять данные формыЗаголовок группы HTML legend - как правильно использовать и оформлятьТег input в HTML - типы атрибуты валидация и примерыТег формы form в HTMLГруппа полей HTML fieldsetАтрибут action в HTML - как правильно задавать адрес отправки формы
Открыть базу знаний

Лучшие курсы по теме

изображение курса

HTML и CSS

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий