За последние три года я сделал больше десятка SPA - от личных кабинетов и CRM на React до дашбордов на Vue для внутренней аналитики. Создание SPA-приложения - это не «взять React и накидать компонентов», а отдельный процесс с прототипированием, выбором архитектуры, настройкой роутинга и интеграцией с бэкендом, который ломается в неожиданных местах, если пропустить один из шагов. Разберу процесс так, как веду его на практике - от постановки задачи до деплоя.
Что такое SPA и когда оно оправдано
SPA (single-page application) - это приложение, где браузер один раз загружает HTML-каркас и JS-бандл, а дальше всё происходит без перезагрузки страницы: переходы между экранами, обновление данных, формы - всё через JavaScript и запросы к API. Отличие от обычного сайта на WordPress или Tilda в том, что там каждая страница - это отдельный запрос на сервер с готовым HTML, а в SPA сервер отдаёт только данные.
SPA имеет смысл, когда пользователь проводит в интерфейсе много времени и работает с данными: личный кабинет, CRM, панель администратора, дашборд, сервис бронирования, внутренний инструмент для сотрудников. Для лендинга или сайта-визитки SPA - избыточное решение: там важнее скорость первой загрузки и индексация в поиске, и с этим справится обычный сайт или Tilda-скрипты для доработки готовых блоков.
Архитектура SPA-приложения: из чего она состоит
При создании SPA-приложения я закладываю четыре слоя, которые потом развиваются независимо друг от друга:
- Клиентское приложение - компоненты, роутинг, состояние (React, Vue, реже Svelte)
- Слой работы с API - обёртка над fetch/axios, кэширование запросов, обработка ошибок сети
- Бэкенд - REST или GraphQL API, обычно на Laravel, Node.js или Django, отдающий JSON
- Инфраструктура - сборка (Vite), деплой, CI, мониторинг ошибок на фронте
Ошибка, которую вижу в чужих проектах чаще всего, - смешивание логики запросов прямо в компонентах. Через полгода такое приложение невозможно рефакторить без риска что-то сломать, потому что один и тот же запрос к API продублирован в пяти местах с разной обработкой ошибок.
Выбор стека для разработки SPA
Стек выбираю под задачу, а не по личным предпочтениям - команда заказчика, бюджет и требования к SEO решают больше, чем «что моднее».
| Стек | Когда беру | Особенность |
|---|---|---|
| React + Vite | CRM, админки, сложная бизнес-логика | Огромная экосистема, легко найти библиотеку под любую задачу |
| Vue 3 | Дашборды, BI-панели, проекты с быстрым стартом | Ниже порог входа для команды заказчика, если у них есть свои фронтендеры |
| Next.js | Когда часть страниц должна индексироваться в поиске | Гибрид SSR и SPA - публичные страницы рендерятся на сервере, личный кабинет работает как SPA |
В моём прайсе веб-сервис или SPA на чистом React/Vue - от 150 000 ₽, CRM-система или админ-панель на React - от 100 000 ₽, дашборд на Vue - от 90 000 ₽. Разброс объясняется объёмом бизнес-логики, а не просто количеством экранов: форма с тремя полями и таблица с фильтрами, сортировкой и экспортом - это разная трудоёмкость даже при одинаковом числе страниц.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Пошаговый процесс создания SPA-приложения
Прототип и техническое задание
Перед тем как открыть редактор кода, я собираю список экранов и переходов между ними - обычно в виде схемы в Figma или даже в виде текстового списка «страница → что на ней → какие действия». На этом этапе всплывает половина требований, о которых заказчик забыл упомянуть в брифе: нужна ли пагинация, что происходит при пустом состоянии таблицы, как обрабатывать права доступа для разных ролей.
Настройка проекта и роутинга
Создаю проект на Vite, подключаю роутер (React Router или Vue Router), настраиваю структуру папок по фичам, а не по типам файлов - то есть не отдельно «все компоненты», «все хуки», «все стили», а папка на каждую фичу со всем, что к ней относится. Это экономит время при доработках: если нужно поправить раздел «Заказы», все связанные файлы лежат рядом, а не разбросаны по трём каталогам.
Работа с состоянием и API
Для состояния беру Zustand или Redux Toolkit в React, Pinia во Vue - глобальный стор только для данных, которые нужны в нескольких местах (авторизация, корзина, текущий пользователь), остальное живёт в локальном состоянии компонента. Запросы к API оборачиваю в React Query или аналог - это снимает половину боли с кэшированием, повторными запросами при ошибке и состояниями загрузки.
Тестирование и деплой
Перед сдачей прогоняю приложение в разных сценариях: медленный интернет через троттлинг в devtools, обрыв соединения посреди запроса, повторные клики по кнопке отправки формы. SPA собирается в статические файлы и деплоится на CDN или Vercel/Netlify, бэкенд разворачивается отдельно - это разделение ответственности упрощает масштабирование каждой части независимо.
Интеграция SPA с бэкендом и внешними сервисами
Самостоятельное SPA без данных - просто красивая оболочка, поэтому бо́льшая часть реальной работы уходит на интеграции. Бэкенд под SPA я обычно поднимаю на Laravel - там из коробки есть авторизация, миграции и готовый REST-слой, это ускоряет разработку API примерно в полтора раза по сравнению с ручной сборкой на голом Node.js. Если у заказчика уже есть бэкенд и нужен только фронтенд поверх готового API - тоже беру такие задачи, но закладываю время на изучение чужой документации API (или на её отсутствие).
Из частых интеграций в SPA: приём оплаты через эквайринг Т‑Банка в личном кабинете, расчёт доставки и статусы заказов через API СДЭК, уведомления пользователям через Telegram-бота на aiogram, когда меняется статус заявки. Для фоновых процессов - синхронизация с CRM, рассылки, обработка вебхуков от платёжной системы - часто выношу логику в n8n, чтобы не городить отдельный сервис под каждую интеграцию. Если нужен бэкенд под конкретный SPA-проект, у меня есть каталог услуг по веб-разработке с актуальными расценками на API, интеграции и техподдержку.
Частые ошибки при разработке SPA-приложений
Собрал список того, что чаще всего аукается после сдачи проекта:
- SPA без SSR для публичных страниц - если часть контента должна попадать в поиск, чистый клиентский рендеринг похоронит SEO, тут нужен Next.js или отдельный лендинг
- Хранение токена авторизации в localStorage без учёта XSS - токен лучше держать в httpOnly cookie, доступной только бэкенду
- Отсутствие состояний загрузки и ошибок - пользователь видит пустой экран на 2 секунды и решает, что приложение зависло
- Переусложнённый стейт-менеджмент с первого дня - Redux с десятком редьюсеров для проекта из пяти экранов ускоряет только написание багов
- Игнорирование лимитов внешних API - если СДЭК или платёжный шлюз режет частые запросы, без ретраев и очередей приложение начнёт падать под нагрузкой
Сроки и стоимость создания SPA-приложения
Веб-сервис или SPA-приложение под ключ у меня стоит от 150 000 ₽ - в эту сумму входит фронтенд, базовый бэкенд и интеграция с одним-двумя внешними сервисами. Если нужен только фронтенд поверх готового API - сумма ниже, ориентируюсь по объёму экранов после разбора ТЗ. Отдельно API/бэкенд на Laravel - от 100 000 ₽, если backend разрастается в самостоятельный сервис с очередями и вебхуками.
По срокам: небольшой личный кабинет с 5-7 экранами занимает 3-4 недели, CRM среднего размера с ролями и отчётами - 6-8 недель, сложный SaaS-продукт с несколькими ролями и биллингом - от 3 месяцев. На рынке у студий за похожий SPA-проект просят от 300 000 до 800 000 ₽, потому что в смету закладывают аккаунт-менеджера, дизайнера и тестировщика отдельными строками - я закрываю разработку сам, поэтому цена ниже при том же результате.
Когда нужен не сайт, а сервис
SaaS / SPA
от 300 000 ₽
Подробнее →Частые вопросы
Сколько времени занимает создание SPA-приложения?
Зависит от количества экранов и сложности бизнес-логики. Простой личный кабинет с базовыми формами занимает 3-4 недели, CRM с ролями пользователей и отчётами - 6-8 недель, крупный SaaS с биллингом и несколькими типами доступа - от 3 месяцев с постепенным релизом функций по частям.
Можно ли продвигать SPA-приложение в поисковой выдаче?
Чистое клиентское SPA поисковики индексируют плохо, потому что контент появляется после выполнения JavaScript. Если нужна индексация - беру гибридный подход на Next.js: публичные страницы (лендинг, блог, карточки товаров) рендерятся на сервере, а личный кабинет или админка работают как обычное SPA поверх того же кода.
Чем SPA отличается от сайта на WordPress или Tilda?
WordPress и Tilda отдают готовый HTML на каждый запрос - это быстрее для первой загрузки и лучше индексируется без доп. настроек, подходит для сайтов с контентом. SPA грузит один раз JS-бандл и дальше работает как приложение - подходит для интерфейсов с частым взаимодействием: таблицы, фильтры, формы, real-time обновления данных.
Какой стек лучше выбрать - React или Vue?
Разницы в возможностях почти нет, оба справляются с любой сложностью SPA. React беру, если в проекте много кастомной бизнес-логики и нужна широкая экосистема готовых библиотек. Vue - если у заказчика уже есть команда фронтендеров с опытом на Vue или нужен более быстрый старт разработки с меньшим порогом входа для новых разработчиков в команде.