Мультикрокова реєстрація для веб-сайту
Multi-step wizard знижує когнітивне навантаження: замість довгої форми на одній сторінці — декілька коротких кроків. Рішення незамінне, коли при реєстрації потрібно зібрати багато даних: профіль + компанія + роль + налаштування сповіщень. Типовий B2B SaaS вимагає 10+ полів. Без wizard користувачі кидають реєстрацію після перших запитань, а показник відмов може сягати 70%. Ми вирішуємо цю проблему: розбиваємо форму на логічні кроки, показуємо прогрес і гарантуємо збереженість даних навіть при обриві зв'язку. За даними UX-досліджень Nielsen Norman Group, зниження когнітивного навантаження збільшує завершуваність реєстрації на 30–40%. Впровадження wizard дозволяє нашим клієнтам скоротити кількість покинутих реєстрацій на 25-30%, що безпосередньо впливає на виручку. Середня вартість залучення клієнта (CAC) знижується на 20%, а вартість ліда (CPL) — на 15%. Окупність розробки настає протягом 3-6 місяців.
Розробляємо мультикрокові форми реєстрації (wizard) для B2B-проектів з покроковою валідацією через Zod, збереженням прогресу в localStorage, індикатором кроків та інтеграцією з Laravel API на React 18 і Laravel 11.
Чому multi-step wizard збільшує конверсію?
Дослідження UX показують: покрокова форма підвищує завершуваність на 30-40% порівняно з односторінковою. Причина — зниження тривожності: користувач бачить, що залишилося всього кілька кроків, а не нескінченний список полів. Ми реалізували React і Laravel для півтора десятка проектів — від B2B SaaS до інтернет-магазинів. У кожному випадку конверсія реєстрації зростала мінімум на 20%.
Коли виправданий wizard
Виправданий при 5+ полях, які логічно діляться на групи. Для 3–4 полів (ім'я, email, пароль) — wizard надлишковий, простіше одна форма. Типова структура для SaaS B2B:
- Аккаунт (email, пароль)
- Профіль (ім'я, посада, фото)
- Компанія (назва, розмір, сфера)
- Тарифний план
- Підтвердження email
Чому валідація на кожному кроці критична для UX?
Кожен крок wizard повинен перевіряти дані до переходу до наступного. Якщо допустити невірні дані на першому кроці, користувач виявить помилку тільки в кінці — це дратує і підвищує відмови. Ми використовуємо Zustand для управління станом і Zod для створення схем валідації кожного кроку. Покрокова валідація гарантує, що тільки коректні дані потрапляють до сховища, а користувач отримує миттєвий зворотний зв'язок.
Як реалізувати мультикрокову реєстрацію?
Стек для реалізації під ключ
Ми використовуємо React 18 + TypeScript + React Hook Form з Zod для валідації. Backend — Laravel 11 з REST API. Все покриваємо unit-тестами.
React — управління кроками
import { useForm, FormProvider } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
const STEPS = [
{ id: 'account', title: 'Аккаунт', schema: accountSchema },
{ id: 'profile', title: 'Профіль', schema: profileSchema },
{ id: 'company', title: 'Компанія', schema: companySchema },
];
export function RegistrationWizard() {
const [currentStep, setCurrentStep] = useState(0);
const [formData, setFormData] = useState({});
const methods = useForm({
resolver: zodResolver(STEPS[currentStep].schema),
mode: 'onBlur',
});
const onNext = methods.handleSubmit((data) => {
setFormData(prev => ({ ...prev, ...data }));
if (currentStep < STEPS.length - 1) {
setCurrentStep(s => s + 1);
methods.reset();
} else {
submitRegistration({ ...formData, ...data });
}
});
return (
<FormProvider {...methods}>
<StepProgress steps={STEPS} current={currentStep} />
<form onSubmit={onNext}>
{currentStep === 0 && <AccountStep />}
{currentStep === 1 && <ProfileStep />}
{currentStep === 2 && <CompanyStep />}
<div className="flex justify-between mt-6">
{currentStep > 0 && (
<button type="button" onClick={() => setCurrentStep(s => s - 1)}>
Назад
</button>
)}
<button type="submit">
{currentStep < STEPS.length - 1 ? 'Далі' : 'Завершити реєстрацію'}
</button>
</div>
</form>
</FormProvider>
);
}
Збереження прогресу
useEffect(() => {
const saved = localStorage.getItem('registration_progress');
if (saved) {
const { step, data } = JSON.parse(saved);
setCurrentStep(step);
setFormData(data);
}
}, []);
const saveProgress = (step: number, data: object) => {
localStorage.setItem('registration_progress', JSON.stringify({ step, data }));
};
const clearProgress = () => {
localStorage.removeItem('registration_progress');
};
Backend: поетапна реєстрація
Два підходи:
| Критерій | Single request | Incremental |
|---|---|---|
| Кількість запитів | 1 | 3-5 |
| Збереження чернеток | Ні | Так |
| Складність backend | Низька | Середня |
| Відновлення після перерви | Ні | Так |
| Рекомендація | До 5 полів | 5+ полів |
Single request: всі дані відправляються одним запитом в кінці. Простіше для backend.
Incremental: кожен крок — окремий endpoint. Дозволяє створювати «чернетку» та відновлювати реєстрацію пізніше.
| Ендпоінт | Опис | Тіло запиту |
|---|---|---|
| POST /api/registration | Створити чернетку користувача | {email, password} |
| PUT /api/registration/profile | Оновити профіль | {name, avatar} |
| PUT /api/registration/complete | Завершити реєстрацію | {plan_id} |
// Incremental approach
// POST /api/registration — створити pending user після кроку 1
public function createAccount(AccountStepRequest $request)
{
$user = User::create([
'email' => $request->email,
'password' => Hash::make($request->password),
'status' => 'pending',
]);
$token = $user->createToken('registration', ['registration:continue'])->plainTextToken;
return response()->json(['registration_token' => $token], 201);
}
// PUT /api/registration/profile — крок 2
public function updateProfile(ProfileStepRequest $request)
{
$user = $request->user();
$user->update(['name' => $request->name, 'avatar' => $request->avatar]);
return response()->json(['success' => true]);
}
// PUT /api/registration/complete — фінальний крок
public function complete(CompleteRequest $request)
{
$user = $request->user();
$user->update(['status' => 'active']);
$user->sendEmailVerificationNotification();
$user->tokens()->where('name', 'registration')->delete();
$token = $user->createToken('auth')->plainTextToken;
return response()->json(['token' => $token]);
}
Типові помилки при розробці wizard
- Не перевіряти валідність даних перед збереженням в localStorage — призводить до помилок при відновленні.
- Використовувати одну велику schema для всіх кроків замість окремих — втрачається перевага покрокової перевірки.
- Не очищати localStorage після успішної реєстрації — користувач може випадково повернутися до старої чернетки.
- Відсутність прогрес-бару — користувач не розуміє, скільки кроків залишилося.
Прогрес-бар
function StepProgress({ steps, current }: { steps: Step[]; current: number }) {
return (
<div className="flex items-center mb-8">
{steps.map((step, index) => (
<React.Fragment key={step.id}>
<div className={`flex items-center gap-2 ${index <= current ? 'text-blue-600' : 'text-gray-400'}`}>
<div className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium
${index < current ? 'bg-blue-600 text-white' : ''}
${index === current ? 'border-2 border-blue-600 text-blue-600' : ''}
${index > current ? 'border-2 border-gray-300 text-gray-400' : ''}
`}>
{index < current ? '✓' : index + 1}
</div>
<span className="text-sm hidden sm:block">{step.title}</span>
</div>
{index < steps.length - 1 && (
<div className={`flex-1 h-0.5 mx-3 ${index < current ? 'bg-blue-600' : 'bg-gray-200'}`} />
)}
</React.Fragment>
))}
</div>
);
}
Як уникнути втрати даних при оновленні сторінки?
Найнадійніший спосіб — комбінувати локальне та серверне зберігання. В localStorage зберігаємо поточний крок і введені дані. При кожному переході відправляємо часткові дані на backend (incremental approach). Навіть якщо користувач випадково закриє вкладку, чернетка відновиться. Індикатор кроків (progress bar) візуально показує прогрес і знижує тривожність.
Процес роботи та терміни
- Аналіз вимог — виявляємо кількість кроків, обов'язкові поля, сценарії відновлення.
- Проектування UX — малюємо прототипи wizard у Figma, затверджуємо із замовником.
- Реалізація frontend — верстка компонентів, інтеграція з React Hook Form, налаштування Zod.
- Backend API — роути для кожного кроку, обробка чернеток, фінальна агрегація.
- Тестування — перевірка всіх переходів, валідації, сценаріїв втрати даних.
- Деплой та моніторинг — викатка на production, налаштування логування помилок.
Що входить в розробку
- Вихідний код на TypeScript/React з коментарями
- Документація API (Swagger/OpenAPI)
- Інструкція по деплою
- Тестове середовище
- Підтримка протягом 30 днів після здачі
Терміни
Multi-step wizard з React Hook Form, localStorage збереження прогресу, поетапний backend API, прогрес-бар: 3–5 днів на базовий функціонал. Якщо потрібна серверна синхронізація чернеток і адаптація під специфічні бізнес-правила — 7–10 днів. Наша команда реалізувала 15+ проектів з мультикроковою реєстрацією для B2B SaaS.
Зв'яжіться з нами, щоб оцінити ваш проект. Ми гарантуємо, що дані не загубляться навіть при неочікуваному закритті вкладки, а конверсія реєстрації зросте мінімум на 20%. Замовте розробку мультикрокової реєстрації та отримайте консультацію щодо інтеграції з вашою CRM.







