Разработка квиза (Quiz) с расчётом результата на сайте

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

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка квиза (Quiz) с расчётом результата на сайте
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Разработка квиза (Quiz) с расчётом результата на сайте

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

Типы квизов

Типологический — каждый ответ прибавляет очки к одному или нескольким «профилям». В конце побеждает профиль с максимальным счётом. Используется для «Какой вы тип клиента», «Подберём тариф под вас».

Балльный — ответы дают числовые очки, итоговый результат определяется диапазоном. Типично для тестов знаний, оценки уровня.

Ветвящийся (branching) — следующий вопрос зависит от ответа на предыдущий. Позволяет строить сложные сценарии с разными итогами.

Рекомендательный — квиз собирает параметры и на выходе рекомендует конкретный продукт, тариф, специалиста.

Структура данных

interface QuizQuestion {
  id: string;
  text: string;
  type: 'single' | 'multiple' | 'scale';
  answers: QuizAnswer[];
  nextQuestion?: string | ((answers: Record<string, string[]>) => string); // для branching
}

interface QuizAnswer {
  id: string;
  text: string;
  scores: Record<string, number>; // { profile_a: 3, profile_b: 1 }
  image?: string;
}

interface QuizResult {
  id: string;
  title: string;
  description: string;
  recommendation?: string;
  cta?: { text: string; url: string };
  minScore?: number; // для балльного типа
  maxScore?: number;
}

Движок расчёта

class QuizEngine {
  constructor(questions, results) {
    this.questions = questions;
    this.results = results;
    this.answers = {}; // questionId -> answerId[]
    this.scores = {};
  }

  answer(questionId, answerIds) {
    this.answers[questionId] = answerIds;

    const question = this.questions.find(q => q.id === questionId);
    for (const answerId of answerIds) {
      const answer = question.answers.find(a => a.id === answerId);
      if (!answer?.scores) continue;
      for (const [profile, score] of Object.entries(answer.scores)) {
        this.scores[profile] = (this.scores[profile] || 0) + score;
      }
    }
  }

  getNextQuestion(currentId) {
    const question = this.questions.find(q => q.id === currentId);
    if (typeof question.nextQuestion === 'function') {
      return question.nextQuestion(this.answers);
    }
    return question.nextQuestion;
  }

  calculateResult() {
    // Типологический: победитель по очкам
    const [topProfile] = Object.entries(this.scores)
      .sort(([, a], [, b]) => b - a);

    return this.results.find(r => r.id === topProfile?.[0]) ?? this.results[0];
  }

  getTotalScore() {
    return Object.values(this.scores).reduce((s, v) => s + v, 0);
  }
}

React-компонент квиза

function Quiz({ config }) {
  const engine = useRef(new QuizEngine(config.questions, config.results));
  const [step, setStep] = useState(0);
  const [selected, setSelected] = useState([]);
  const [result, setResult] = useState(null);
  const [leadCaptured, setLeadCaptured] = useState(false);

  const currentQ = config.questions[step];
  const progress = ((step / config.questions.length) * 100).toFixed(0);

  function handleNext() {
    engine.current.answer(currentQ.id, selected);
    setSelected([]);

    if (step + 1 >= config.questions.length) {
      setResult(engine.current.calculateResult());
    } else {
      setStep(s => s + 1);
    }
  }

  if (result && !leadCaptured) {
    return <LeadCapture onSubmit={(contact) => {
      submitLead({ contact, result, answers: engine.current.answers });
      setLeadCaptured(true);
    }} />;
  }

  if (result && leadCaptured) {
    return <QuizResult result={result} score={engine.current.getTotalScore()} />;
  }

  return (
    <div className="quiz">
      <ProgressBar value={progress} />
      <QuizQuestion
        question={currentQ}
        selected={selected}
        onSelect={setSelected}
      />
      <button onClick={handleNext} disabled={!selected.length}>
        {step + 1 < config.questions.length ? 'Далее' : 'Узнать результат'}
      </button>
    </div>
  );
}

Захват лида перед результатом

Классическая механика: пользователь проходит все вопросы, но результат видит только после ввода email (или телефона). Конверсия выше, чем у обычной формы подписки, потому что человек уже вложил время.

function LeadCapture({ onSubmit }) {
  const { register, handleSubmit } = useForm();

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <h3>Ваш результат готов!</h3>
      <p>Укажите email, чтобы получить персональные рекомендации</p>
      <input {...register('email', { required: true })} type="email" placeholder="[email protected]" />
      <input {...register('name')} placeholder="Имя (необязательно)" />
      <button type="submit">Показать результат</button>
    </form>
  );
}

Аналитика

Для квизов важно отслеживать не только финальные конверсии, но и dropout на каждом шаге:

// GTM / GA4
function trackStep(questionIndex, questionId) {
  window.dataLayer?.push({
    event: 'quiz_step',
    quiz_step: questionIndex + 1,
    quiz_question_id: questionId,
  });
}

function trackCompletion(resultId, score) {
  window.dataLayer?.push({
    event: 'quiz_complete',
    quiz_result: resultId,
    quiz_score: score,
  });
}

Анимация переходов

Переходы между вопросами улучшают ощущение от продукта. Простая анимация через CSS:

.quiz-question {
  animation: slideIn 0.3s ease-out;
}

@keyframes slideIn {
  from { opacity: 0; transform: translateX(24px); }
  to   { opacity: 1; transform: translateX(0); }
}

Для React — framer-motion с AnimatePresence для плавного удаления предыдущего вопроса.

Сроки

Простой балльный квиз на 5–10 вопросов с захватом лида и результатом — 3–4 рабочих дня. Ветвящийся квиз с несколькими профилями, анимацией, интеграцией в CRM и A/B-тестированием конфигураций — 8–12 дней.