Анатомия одной попытки: как подключить внешний API к Squarespace и не слить ключи

Год назад ко мне пришел владелец нишевого магазина мебели на Squarespace 7.1. Задача звучала невинно: сделать калькулятор доставки прямо в карточке товара, запрашивая точный расчет через API транспортной компании. Штатный верстальщик заказчика предпринял смелую попытку решить задачу «в лоб». Он открыл Code Injection, написал пару десятков строк на чистом JavaScript с обычным fetch() и зашил туда боевой Bearer-токен сервиса.

Через четыре дня баланс аккаунта транспортной компании улетел в минус на 92 000 рублей. Скрипт-кидди просто открыли вкладку Network в Chrome DevTools, скопировали ключ и прогнали через него сотни тысяч своих тяжелых запросов. Это классика. Первая попытка подружить закрытый конструктор с внешним миром почти всегда заканчивается либо дырой в безопасности, либо разбитыми надеждами.

Две стены Squarespace: CORS и браузерный публичный код

Когда создается нестандартная squarespace api интеграция, разработчик моментально упирается в архитектурный тупик. Squarespace прекрасен для контента, портфолио и типового e-commerce. Но под капотом это закрытая система. У вас нет доступа к Node.js-рантайму, нет возможности выполнять серверный код на их мощностях (если вы не готовы переходить на чудовищно сложный Squarespace Developer Platform с заморозкой шаблона).

Вы остаетесь наедине с фронтендом. И тут возникают две проблемы:

Первая — cors ошибка squarespace. Вы пытаетесь постучаться из браузера пользователя (с домена yourbrand.squarespace.com) на чужой сервер (например, в Airtable, OpenAI или закрытый складской сервис). Сторонний сервер справедливо отвечает блокировкой: заголовок Access-Control-Allow-Origin не настроен под ваш сайт. Браузер выбрасывает красный еррор в консоль, данные не приходят.

Вторая проблема куда опаснее. Чтобы победить CORS или просто авторизоваться, люди пытаются передать приватный API-секрет прямо в заголовках фронтенд-запроса. Запомните: все, что попадает в браузер — от HTML до обфусцированного JS — принадлежит всему интернету. Спрятать ключ на клиенте невозможно физически.

Почему no-code костыли только раздражают пользователей

Вторая типичная попытка обойти ограничение — прокинуть данные через интеграторы вроде Zapier или Make. Схема выглядит так: JS на Squarespace стреляет в вебхук Zapier, тот запрашивает API, ждет, переваривает и отдает JSON обратно.

На бумаге красиво. На практике задержка ответа (latency) составляет от 2.5 до 6 секунд. Для динамического интерфейса — живого поиска, валидации промокода, интерактивного калькулятора — три секунды ожидания означают смерть конверсии. Пользователь успевает дважды кликнуть на кнопку, подумать, что сайт завис, и закрыть вкладку. К тому же лимиты на вызовы вебхуков в no-code платформах сгорают с пугающей скоростью.

Squarespace — это сайт без сервера в классическом понимании разработчика. Полноценный squarespace без бэкенда не может безопасно работать с внешними данными напрямую. Ему нужна крошечная, быстрая прослойка.

Решение: тонкий Nginx-прокси за 50 миллисекунд

Вместо того чтобы переписывать сайт на Next.js или городить серверлесс-функции на AWS Lambda с кучей зависимостей, мы используем изолированный легковесный reverse proxy на базе Nginx. Это изящный фильтр, который берет на себя всю грязную работу.

Как работает правильный прокси для api ключей:

1. Изоляция секрета. Ваш скрипт на Squarespace отправляет обычный открытый запрос на ваш собственный эндпоинт, например https://proxy.yourdomain.com/v1/calculate. Никаких ключей и паролей в теле запроса нет.

2. Фильтрация источников. Прокси проверяет заголовок Origin. Если запрос пришел не с вашего конкретного сайта на Squarespace — сервер моментально сбрасывает соединение с кодом 403. Сторонние сайты не смогут паразитировать на вашем ресурсе.

3. Инъекция заголовков. Сам Nginx на лету подставляет приватный ключ (Authorization: Bearer sk-live-...), скрытый в конфигурации сервера, и перенаправляет запрос к целевому сервису.

4. Снятие CORS-блока. Прокси добавляет необходимые заголовки Access-Control-Allow-Origin: https://yourbrand.com в ответ и возвращает готовый JSON в браузер клиента. Время выполнения — 40–80 миллисекунд вместо нескольких секунд у no-code связок.

location /api/v1/data {
    # Разрешаем запросы только с вашего сайта
    if ($http_origin ~* (https?://(www\.)?yourbrand\.com)) {
        add_header 'Access-Control-Allow-Origin' '$http_origin' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Content-Type' always;
    }

    # Прячем секрет внутри сервера
    proxy_set_header Authorization "Bearer SECRET_API_KEY_HERE";
    proxy_pass https://api.targetservice.com/v1/endpoint;
    proxy_ssl_server_name on;
}

Такая архитектура не требует поддержки сложного серверного кода. Сервер не хранит базы данных, не ломается от обновлений пакетов и спокойно выдерживает миллионы запросов в месяц на самом дешевом VPS за пару долларов.

Не изобретайте велосипед

Если вам нужно связать форму, виджет или калькулятор на конструкторе с внешним миром, не пытайтесь обмануть архитектуру браузера. Обфускация кода и публичные API-ключи — это мина замедленного действия. Рано или поздно кто-то вытащит ваш токен.

Мы в GuardLabs настраиваем эту инфраструктуру регулярно. Если вы уперлись в ограничения платформы и вам нужен быстрый, безопасный прокси для внешнего API на Squarespace-сайте (без бэкенда), мы развернем его, настроим CORS, закроем ключи в защищенном контуре и выдадим вам готовый чистый JS-сниппет. Всё заводится за один рабочий день и работает годами без сбоев.