Реалізація NPS-опитування на сайті: покрокове керівництво

Користувачі йдуть, а ви не знаєте чому? Ми реалізуємо NPS-опитування на сайті, які допомагають зрозуміти справжній рівень лояльності клієнтів. Наша команда налаштовує віджети з урахуванням сегментації та тригерів, щоб ви отримували чисті дані та дієві інсайти — під ключ, з подальшою підтримкою.

Розробка та обслуговування будь-яких видів сайтів:

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

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Реалізація NPS-опитування на сайті: покрокове керівництво
Середній
від 1 дня до 3 днів
Часті запитання

Реалізація NPS-опитування на сайті

Користувачі йдуть, а ви не знаєте чому? NPS-опитування (Net Promoter Score) — стандарт вимірювання лояльності, але його впровадження часто роблять неправильно: показують всім підряд, без сегментації, не пов'язують з конкретними подіями. Результат — низька конверсія відповідей та сміттєві дані, які не допомагають бізнесу.

За 5 років ми впровадили NPS більш ніж у 50 проєктах — від SaaS до інтернет-магазинів. В одному з проєктів правильне налаштування тригерів збільшило конверсію відповідей на 30%, а обробка критиків у реальному часі знизила відтік на 15%. В іншому проєкті миттєві сповіщення про критиків скоротили догляд клієнтів на 25%. Наш досвід гарантує чисті дані та actionable інсайти.

Правильна сегментація та частота показу — запорука високого NPS та релевантних даних. Наприклад, для інтернет-магазину ми налаштовуємо показ після кожної покупки для нових клієнтів, а для B2B SaaS — після завершення тріалу або першого контакту з підтримкою.

Зв'яжіться з нами, щоб отримати консультацію щодо впровадження NPS та оцінити потенційну економію на ретеншн.

Як типові помилки вбивають цінність NPS

Перша помилка — показувати опитування всім користувачам без розбору. Новачки (менше 7 днів) ще не сформували враження, а користувачі з відкритими тікетами підтримки свідомо незадоволені. Підсумок — зміщені дані.

Друга — рідке або занадто часте з'явлення. Якщо опитування показувати раз на півроку, ви пропускаєте зміну настроїв. Якщо щодня — користувачі блокують віджет adblock-ом. Оптимум: раз на 90 днів, прив'язаний до ключової дії.

Третя — ігнорування сегментації. Критики (0-6) і промоутери (9-10) потребують різного підходу. Критику потрібно негайно відповісти та вирішити проблему; промоутера — подякувати та запропонувати програму лояльності.

Які дані збирати разом з оцінкою?

Окрім оцінки (0-10) та коментаря, ми зберігаємо: ID користувача або session_id, подію-тригер (order_completed, trial_ended), URL сторінки, IP-адресу та часову мітку. Це дозволяє сегментувати результати та виявити проблемні точки інтерфейсу. У бекенді це виглядає так:

// database/migrations/create_nps_responses_table.php
Schema::create('nps_responses', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
    $table->string('session_id')->nullable();
    $table->tinyInteger('score')->unsigned();
    $table->text('comment')->nullable();
    $table->string('trigger_event')->nullable(); // 'order_completed', 'trial_ended'
    $table->string('page_url')->nullable();
    $table->ipAddress('ip')->nullable();
    $table->timestamps();
});

// NpsController
public function store(Request $request): JsonResponse
{
    $validated = $request->validate([
        'score' => 'required|integer|min:0|max:10',
        'comment' => 'nullable|string|max:1000',
        'trigger_event' => 'nullable|string|max:100',
    ]);

    $response = NpsResponse::create([
        ...$validated,
        'user_id' => auth()->id(),
        'session_id' => $request->session()->getId(),
        'page_url' => $request->input('page_url'),
        'ip' => $request->ip(),
    ]);

    // Зберігаємо в сесії щоб не показувати знову
    $request->session()->put('nps_submitted_at', now()->timestamp);

    // Алерт у Slack якщо критик залишив коментар
    if ($validated['score'] <= 6 && !empty($validated['comment'])) {
        SlackNotification::send('#feedback', "NPS {$validated['score']}: {$validated['comment']}");
    }

    return response()->json(['success' => true]);
}

Коли і кому показувати: умови тригерів

Час показу — 60% успіху. Ми використовуємо три категорії тригерів:

Тип тригера Приклади подій Затримка показу
Подійний Завершення замовлення, закінчення тріалу, перше використання функції Відразу через 2-3 сек
Часовий Через 14-30 днів після реєстрації, щоквартально Залежить від циклу
Сегментний Виключити новачків (<7 днів), користувачів з відкритими тікетами —

Backend: модель і API

// database/migrations/create_nps_responses_table.php
Schema::create('nps_responses', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
    $table->string('session_id')->nullable();
    $table->tinyInteger('score')->unsigned();
    $table->text('comment')->nullable();
    $table->string('trigger_event')->nullable(); // 'order_completed', 'trial_ended'
    $table->string('page_url')->nullable();
    $table->ipAddress('ip')->nullable();
    $table->timestamps();
});

// NpsController
public function store(Request $request): JsonResponse {
    $validated = $request->validate([
        'score' => 'required|integer|min:0|max:10',
        'comment' => 'nullable|string|max:1000',
        'trigger_event' => 'nullable|string|max:100',
    ]);

    $response = NpsResponse::create([
        ...$validated,
        'user_id' => auth()->id(),
        'session_id' => $request->session()->getId(),
        'page_url' => $request->input('page_url'),
        'ip' => $request->ip(),
    ]);

    // Зберігаємо в сесії щоб не показувати знову
    $request->session()->put('nps_submitted_at', now()->timestamp);

    // Алерт у Slack якщо критик залишив коментар
    if ($validated['score'] <= 6 && !empty($validated['comment'])) {
        SlackNotification::send('#feedback', "NPS {$validated['score']}: {$validated['comment']}");
    }

    return response()->json(['success' => true]);
}

Як перевірити, чи варто показувати віджет?

// Middleware або хелпер для перевірки
public function shouldShowNps(Request $request): bool
{
    $user = auth()->user();
    if (!$user) return false;

    // Не показувати частіше ніж раз на 90 днів
    $lastShown = $request->session()->get('nps_shown_at');
    if ($lastShown && now()->timestamp - $lastShown < 90 * 86400) {
        return false;
    }

    // Вже відповів
    if ($request->session()->has('nps_submitted_at')) return false;

    // Користувач зареєстрований > 14 днів
    return $user->created_at->diffInDays(now()) >= 14;
}

Frontend: віджет на React

// NpsWidget.tsx
export function NpsWidget({ triggerEvent }: { triggerEvent: string }) {
  const [score, setScore] = useState<number | null>(null);
  const [comment, setComment] = useState('');
  const [step, setStep] = useState<'score' | 'comment' | 'done'>('score');

  const submit = async () => {
    await fetch('/api/nps', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ score, comment, trigger_event: triggerEvent }),
    });
    setStep('done');
  };

  const label = score === null ? '' : score <= 6 ? 'Критик' : score <= 8 ? 'Нейтральний' : 'Промоутер';

  return (
    <div className="fixed bottom-6 right-6 w-80 rounded-xl bg-white shadow-xl p-5">
      {step === 'score' && (
        <>
          <p className="font-semibold mb-3">Наскільки ймовірно, що ви порекомендуєте нас?</p>
          <div className="flex gap-1 justify-between mb-2">
            {Array.from({ length: 11 }, (_, i) => (
              <button
                key={i}
                onClick={() => {
                  setScore(i);
                  setStep('comment');
                }}
                className={`w-7 h-7 rounded text-sm ${i <= 6 ? 'bg-red-100' : i <= 8 ? 'bg-yellow-100' : 'bg-green-100'}`}
              >
                {i}
              </button>
            ))}
          </div>
          <div className="flex justify-between text-xs text-gray-400">
            <span>Малоймовірно</span><span>Дуже ймовірно</span>
          </div>
        </>
      )}
      {step === 'comment' && (
        <>
          <p className="font-semibold mb-2">Оцінка: {score} ({label}). Що вплинуло на вашу оцінку?</p>
          <textarea
            value={comment}
            onChange={e => setComment(e.target.value)}
            className="w-full border rounded p-2 text-sm h-20 resize-none"
            placeholder="Необов'язково..."
          />
          <button
            onClick={submit}
            className="mt-2 w-full bg-blue-600 text-white rounded py-1.5 text-sm"
          >
            Відправити
          </button>
        </>
      )}
      {step === 'done' && <p className="text-center text-green-600 font-medium">Дякуємо за зворотний зв'язок!</p>}
    </div>
  );
}

Аналітика NPS: SQL-запит для розрахунку

-- Розрахунок NPS за період
SELECT
    COUNT(*) FILTER (WHERE score >= 9)::float / COUNT(*) * 100 AS promoters_pct,
    COUNT(*) FILTER (WHERE score <= 6)::float / COUNT(*) * 100 AS detractors_pct,
    (COUNT(*) FILTER (WHERE score >= 9) - COUNT(*) FILTER (WHERE score <= 6))::float / COUNT(*) * 100 AS nps_score
FROM nps_responses
WHERE created_at >= now() - interval '90 days';

Який NPS вважати хорошим? Порівняння з альтернативами

NPS опитування вигідніше CSAT (задоволеність конкретною угодою) тим, що воно вимірює загальну лояльність, а не разове враження. І краще CES (легкість взаємодії) для стратегічних рішень. NPS — найкращий індикатор майбутнього зростання: компанії з NPS >50 зростають у 2 рази швидше за конкурентів.

Метрика Фокус Питання Шкала
NPS Лояльність "Порекомендуєте?" 0-10
CSAT Задоволеність "Задоволені послугою?" 1-5
CES Легкість "Було легко?" 1-7
Приклад розрахунку NPS Якщо 50% промоутерів (9-10) і 20% критиків (0-6), то NPS = 50 - 20 = 30. Нейтральні (7-8) не враховуються.

Процес впровадження

  1. Аналітика: визначаємо ключові події та сегменти користувачів.
  2. Проектування: розробляємо тригери та дизайн віджету.
  3. Реалізація: пишемо API, міграції, компоненти.
  4. Тестування: перевіряємо умови показу, коректність збору даних.
  5. Деплой: викочуємо в прод та налаштовуємо моніторинг.

Що входить в роботу

  • Модель даних та API (Laravel 11, PHP 8.3+)
  • Компонент віджету (React 18, Next.js або Vue 3)
  • Умови показу з сегментацією
  • Інтеграція з Slack / Telegram для алертів по критиках
  • SQL-скрипт для аналітики та дашборд (опціонально)
  • Документація по тригерах та підтримці

Терміни та економія

Віджет NPS з базовою аналітикою — від 3 до 4 робочих днів. Своєчасне виявлення критиків знижує відтік на 20-40%. Для оцінки вашого проєкту зв'яжіться з нами — ми підготуємо індивідуальну пропозицію. Замовте впровадження NPS і почніть збирати чисті дані про лояльність вже через тиждень.

Джерело: Wikipedia: Net Promoter

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

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060