Использование форм и функций Netlify для создания виджета подписки на рассылку
Бессерверная функция (иногда называемая облачной функцией) – это фрагмент кода, который можно написать, разместить и запустить вне сайта или приложения. На самом деле эти функции выполняются на сервере. Но вам не нужно создавать его или поддерживать.
Задача: создать форму подписки на рассылку
Для своего сайта я хочу создать форму подписки на рассылку. Условия задачи следующие:
- Форма должна работать без JavaScript – используя только CSS и HTML.
- Форма не должна иметь внешних зависимостей.
- Форма должна использовать бессерверные функции. Вместо отправки данных на сервис рассылки сделаем это с помощью бессерверных функций.
Познакомьтесь с командой: 11ty, Netlify и Buttondown
Мой ресурс построен с использованием статического генератора сайтов 11ty. Он позволяет разрабатывать шаблоны и компоненты на HTML. В нем мы и создадим нашу форму.
За развертывание сайта отвечает сервис Netlify. Он позволяет нам воспользоваться преимуществами бессерверных технологий:
- Netlify может развертываться автоматически из репозитория GitHub. Я могу написать свой код, выполнить pull-запрос и проверить его работоспособность. Существуют инструменты для локального тестирования бессерверных функций, но Netlify упрощает тестирование в режиме онлайн.
- Формы Netlify обрабатывают всю отправку данных. Вместо написания кода обработки форм, я настрою HTML-код с помощью нескольких простых атрибутов и позволю Netlify сделать остальное.
- Функции Netlify позволяют выполнять действия с данными из моих форм. Я напишу код отправки писем своему сервису email-рассылки и сообщу Netlify, когда необходимо запускать этот код.
Кроме этого я буду управлять списком подписчиков с помощью Buttondown. Это провайдер email-рассылок с простым в использовании API.
Форма
Вот HTML-код формы подписки с некоторыми дополнениями для работы с формами Netlify.
<form class="email-form" name="newsletter" method="POST" data-netlify="true" netlify-honeypot="bot-field">
<div hidden aria-hidden="true">
<label>
Don’t fill this out if you're human:
<input name="bot-field" />
</label>
</div>
<label for="email">Your email address</label>
<div>
<input type="email" name="email" placeholder="Email" id="email" required />
<button type="submit">Subscribe</button>
</div>
</form>
Я установил для атрибута data-netlify значение true, чтобы привязать Netlify к обработке формы.
Первое поле формы называется bot-field. Я указываю Netlify следить за любыми подозрительными сообщениями, устанавливая атрибут netlify-honeypot в значение bot-field. Затем я скрываю это поле от пользователей с помощью атрибутов html hidden и aria-hidden. Люди не смогут заполнить это ложное поле.
Если форма отправляется с данными в поле bot-field, Netlify узнает, что данные поступают от робота, и игнорирует ввод. Кроме этого Netlify автоматически фильтрует подозрительные сообщения с помощью Askimet.
Следующее поле формы предназначено для ввода email. Я указал тип поля email и что оно обязательно для заполнения.

Прогрессивные улучшения на JavaScript
По умолчанию Netlify перенаправляет пользователей после заполнения формы на страницу Thank You Page. Но мне это не нужно. Я написал функцию для отправки данных формы без перенаправления.
const processForm = form => {
const data = new FormData(form)
data.append('form-name', 'newsletter');
fetch('/', {
method: 'POST',
body: data,
})
.then(() => {
form.innerHTML = `<div class="form--success">Almost there! Check your inbox for a confirmation e-mail.</div>`;
})
.catch(error => {
form.innerHTML = `<div class="form--error">Error: ${error}</div>`;
})
}
Когда я предоставляю данные формы этой функции через переменную form, она отправляет их с помощью встроенного Fetch API.
Приведенная ниже функция вызывается всякий раз, когда пользователь нажимает кнопку Submit в форме:
const emailForm = document.querySelector('.email-form')
if (emailForm) {
emailForm.addEventListener('submit', e => {
e.preventDefault();
processForm(emailForm);
})
}
Этот обработчик прогрессивно улучшает поведение формы. Поэтому даже если у пользователя отключен JavaScript, форма все равно будет работать!

Бессерверная функция
Чтобы создать функцию Netlify необходимо выполнить следующие шаги:
- Напишите функцию в файле JavaScript.
- Сообщите Netlify, где необходимо искать функцию в файле toml проекта.
- Добавьте переменные окружения, которые понадобятся. Это можно сделать через интерфейс администратора Netlify. Переменная окружения – это, например, ключ API.
Когда вы запустите свой сайт, функция будет готова к работе.
Функция для моего сайта расположена в папке functions. Поэтому в файле netlify.toml записано следующее:
[build]
base = "."
functions = "./functions"
После этого я добавлю в папку functions файл submission-created.js. Это название даст понять Netlify, что скрипт нужно запускать при отправке данных формы. Полный список событий, который поддерживает сценарий обработчика, указаны в документации Netlify. Если вы правильно настроили свою функцию, то увидите ее название в информационной панели функций Netlify.

Содержимое файла submission-created.js выглядит следующим образом:
require('dotenv').config()
const fetch = require('node-fetch')
const { EMAIL_TOKEN } = process.env
exports.handler = async event => {
const email = JSON.parse(event.body).payload.email
console.log(`Recieved a submission: ${email}`)
return fetch('https://api.buttondown.email/v1/subscribers', {
method: 'POST',
headers: {
Authorization: `Token ${EMAIL_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email }),
})
.then(response => response.json())
.then(data => {
console.log(`Submitted to Buttondown:n ${data}`)
})
.catch(error => ({ statusCode: 422, body: String(error) }))
}
Разберем приведенный выше код построчно.
Первая строка подключает библиотеку dotenv, которая позволяет использовать переменные окружения. Они используются для хранения конфиденциальной информации. Например, ключей API.
При локальном запуске проекта я устанавливаю переменные окружения в файле .env репозитория. А также проверяю, указан ли он в файле .gitignore. Для развертывания в Netlify я также настроил переменные окружения в веб-интерфейсе Netlify.

Во второй строке я подключаю небольшую библиотеку node-fetch. Это позволяет использовать Javascript Fetch API. С его помощью мы будем отправлять данные в Buttondown. Netlify автоматически включает эту зависимость, если она указана в файле package.json проекта.
В строке 3 я импортирую свой ключ API из объекта переменных окружения process.env.
В четвертой строке объявляется функция. Netlify будем искать ее в переменной export.handler, поэтому мы определяем ее. Единственный параметр, который нам понадобится, – это значение event, которое содержит все данные из формы.
После извлечения адреса электронной почты из события event с помощью JSON.parse я отправляю его в Buttondown. Вот где используется библиотека node-fetch.
Я отправляю запрос POST к https://api.buttondown.email/v1/subscribers, добавляя мой ключ API в заголовок. У API Buttondown немного функций, поэтому вам не понадобится много времени на их изучение.
Тело запроса POST состоит из полученного адреса электронной почты. Затем я получаю ответ от сервера Buttondown, чтобы продиагностировать любые проблемы. Netlify позволяет легко проверять логи созданных функций с помощью console.log!

Развертывание функции
Теперь все готово к работе. Развертывание проходит быстро: настройте интеграцию Netlify с GitHub, и функция запустится после выполнения команды push в вашем проекте.
Проекты Netlify также можно тестировать локально с помощью Netlify Dev. В зависимости от сложности кода локальная разработка может происходить быстрее.
Выполните команду npm i netlify -g, затем команду netlify dev. Netlify Dev будет использовать файл netlify.toml для настройки и запуска проекта локально, включая бессерверные функции.
Предупреждение: Netlify Dev в настоящее время не позволяет запускать бессерверные функции при отправке форм, поэтому вам придется проверить их с помощью предварительных сборок.
Заключение
Мне понадобилось всего 50 строк кода, чтобы создать функциональную форму подписки на email-рассылку.
Я написал весь код с помощью HTML, CSS и JavaScript, не беспокоясь о серверной части. Форма отбраковывает спам, а посетители могут подписаться на рассылку, даже если у них в браузере отключен JavaScript.