Lead scoring, formularz kontaktowy i pipeline sprzedaży, integracja z Next.js (2026)

lead scoring6 min czytania15 lipca 2026

Autor: DevStudio.it

TL;DR

Lead scoring to liczba lub etykieta (cold / warm / hot), która mówi handlowcowi, kogo dzwonić w pierwszej kolejności, na podstawie danych z formularza, zachowania na stronie i źródła kampanii. Formularz kontaktowy w Next.js to nie tylko mailto:, to Server Action zapisujący lead do PostgreSQL na Branchly Cloud, webhook do CRM i event generate_lead w GA4. Pipeline sprzedaży mapuje statusy (new → qualified → proposal → won) na reguły automatyczne: przypisanie opiekuna, task w CRM, Slack po score > 70. Poniżej: model danych, reguły scoringu, integracja z formularzem i anty-spam.

Dla kogo to jest

  • Firm B2B, które dostają dziesiątki zapytań z formularza miesięcznie i tracą gorące leady w skrzynce „info@"
  • Zespołów sprzedaży bez jasnych kryteriów „kto jest priorytetem", każdy lead wygląda tak samo
  • Developerów wdrażających formularze w Next.js 15 (Server Actions) z zapisem do bazy i CRM
  • Marketingu, które chce połączyć UTM / GA4 z jakością leada, nie tylko liczbą submitów
  • Właścicieli stron po wdrożeniu u DevStudio, rozszerzenie formularza o scoring bez przepisywania całej strony

Fraza (SEO)

lead scoring formularz, pipeline sprzedaży crm, formularz kontaktowy nextjs, server actions lead, integracja crm webhook, punktacja leadów b2b

Od formularza do deala, mapa procesu

Typowy przepływ w projekcie firmowym:

Strona (UTM w sesji) → Submit formularza → Walidacja server-side
    → Zapis Lead w Branchly (PostgreSQL)
    → Obliczenie score + segment
    → Webhook CRM (HubSpot / Pipedrive / custom)
    → Powiadomienie (email / Slack) jeśli hot
    → Pipeline: statusy i zadania handlowca

Formularz to wejście do systemu, nie koniec. Bez zapisu w bazie i CRM każdy submit to mail w skrzynce współdzielonej, niemierzalny w raportach i łatwy do zgubienia.

Model danych, Lead i Score

Prisma na Branchly (fragment ilustracyjny):

model Lead {
  id          String   @id @default(cuid())
  email       String
  company     String?
  budget      String?
  message     String?
  utmSource   String?
  utmCampaign String?
  score       Int      @default(0)
  segment     LeadSegment @default(COLD)
  status      LeadStatus  @default(NEW)
  createdAt   DateTime @default(now())
}

enum LeadSegment {
  COLD
  WARM
  HOT
}

enum LeadStatus {
  NEW
  CONTACTED
  QUALIFIED
  PROPOSAL
  WON
  LOST
}

Score może być sumą wag pól i zdarzeń. Segment ustawiasz progami: 0–39 cold, 40–69 warm, 70+ hot, progi kalibrujesz co kwartał na podstawie conversion rate do won.

Reguły lead scoring, co punktować

Sygnał Przykładowa waga Uzasadnienie
Budżet „> 50 000 PLN" +30 Gotowość inwestycyjna
Firma wypełniona (nie gmail) +20 B2B vs konsument
utm_medium=cpc +15 Płatny ruch, intencja
Strony /cennik, /case-studies w sesji +10 każda Research phase
Wiadomość > 200 znaków +10 Konkretna potrzeba
Email darmowy (gmail, wp) −15 Niższa wartość B2B
Brak telefonu przy wymaganym polu −10 Trudniejszy kontakt

Reguły trzymaj w kodzie (TypeScript) lub tabeli ScoringRule w bazie, drugie podejście pozwala marketingowi zmieniać wagi bez deployu, ale wymaga panelu admin.

Przykład funkcji scoringu:

function computeLeadScore(input: LeadInput, sessionPages: string[]): number {
  let score = 0;
  if (input.company && !isFreeEmail(input.email)) score += 20;
  if (input.budget === '50000+') score += 30;
  if (input.utmMedium === 'cpc') score += 15;
  if (sessionPages.includes('/cennik')) score += 10;
  if ((input.message?.length ?? 0) > 200) score += 10;
  if (isFreeEmail(input.email)) score -= 15;
  return Math.max(0, Math.min(100, score));
}

Formularz Next.js, Server Action end-to-end

Server Action waliduje (Zod), liczy score, zapisuje, wysyła webhook:

'use server';

import { z } from 'zod';
import { prisma } from '@/lib/prisma';
import { computeLeadScore } from '@/lib/scoring';

const schema = z.object({
  email: z.string().email(),
  company: z.string().optional(),
  budget: z.enum(['unknown', '10000', '50000+']).optional(),
  message: z.string().max(5000),
  utmSource: z.string().optional(),
  utmMedium: z.string().optional(),
});

export async function submitContactForm(formData: FormData) {
  const parsed = schema.safeParse(Object.fromEntries(formData));
  if (!parsed.success) return { ok: false, errors: parsed.error.flatten() };

  const score = computeLeadScore(parsed.data, []);
  const segment = score >= 70 ? 'HOT' : score >= 40 ? 'WARM' : 'COLD';

  const lead = await prisma.lead.create({
    data: { ...parsed.data, score, segment: segment as any, status: 'NEW' },
  });

  await fetch(process.env.CRM_WEBHOOK_URL!, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ leadId: lead.id, score, segment }),
  });

  return { ok: true, leadId: lead.id };
}

Formularz kliencki przekazuje UTM z sessionStorage lub hidden fields ustawionych po page_view. Hosting na DevStudioIT Cloud zapewnia stabilny runtime dla Server Actions i env z CRM_WEBHOOK_URL / DATABASE_URL do Branchly.

Pipeline sprzedaży w CRM

Pipeline to kolumny Kanban odpowiadające LeadStatus. Automatyzacje:

Status Akcja automatyczna
NEW + HOT Przypisanie do senior AE, Slack w 15 min
NEW + COLD Email nurturing, brak dzwonienia D0
CONTACTED Task „follow-up za 3 dni"
QUALIFIED Utworzenie deala, szacunek wartości
PROPOSAL Przypomnienie po 7 dniach bez odpowiedzi
WON / LOST Zamknięcie, sync do GA4 offline conversion (opcjonalnie)

CRM (HubSpot, Pipedrive, Salesforce) otrzymuje webhook z score i segment, mapuj na pola custom i listy „Hot leads this week". Jedna definicja segmentu w firmie, inaczej marketing i sales mówią innym językiem.

Anty-spam, RODO i jakość danych

  • Honeypot + rate limit (IP / fingerprint), mniej śmieci w scoringu
  • Double opt-in dla newslettera vs single submit dla zapytania ofertowego, różne zgody w polityce prywatności
  • Consent na przetwarzanie i kontakt handlowy, checkbox przed submit
  • Logi zapisu leada w UE (Branchly), audyt kto widział dane

Score oparty na botach zaniża jakość, filtruj leady z identycznym IP > 5/h.

GA4 i marketing feedback loop

Event generate_lead z parametrami lead_score, lead_segment (custom dimensions) pozwala porównać kampanie nie tylko po liczbie submitów, ale po średnim score. Kampania z tańszym CPC i niższym avg score może być gorsza niż droższa z hot leadami.

FAQ

Ile reguł scoringu na start?

Pięć do siedmiu sygnałów wystarczy. Zbyt skomplikowany model na day one, nikt nie weryfikuje wag. Po 90 dniach porównaj score hot leadów z conversion do won i skoryguj progi.

Czy lead scoring zastępuje rozmowę kwalifikacyjną?

Nie. Score priorytetyzuje kolejkę; kwalifikacja BANT/MEDDIC nadal po stronie handlowca. Automatyczne odrzucanie cold leadów bez polityki firmy to strata długiego taila.

HubSpot vs własna baza na Branchly?

Małe firmy: formularz → Branchly + webhook do HubSpot free. Większe: lead w PostgreSQL jako source of truth, sync dwukierunkowy do CRM. Next.js Server Action pasuje do obu, ważna spójność ID leada.

Jak testować pipeline bez spamowania CRM?

Staging na Branchly + CRM sandbox env (patrz staging z Branchly). Submit testowy z prefiksem [TEST] w company.

Chcesz formularz, który dowozi leady do sprzedaży?

Powiązane wpisy

n8n, automatyzacja formularzy: webhook z Next.js → CRM → Slack (2026)
6 min czytania
Monitoring błędów w Next.js, Sentry w produkcji, alerty i scrubbing PII (2026)
6 min czytania
Next.js 15 Server Actions vs Route Handlers, formularze kontaktowe w 2026
10 min czytania

O autorze

Budujemy szybkie strony WWW, aplikacje web/mobile, chatboty AI i hosting — z naciskiem na SEO i konwersję.

Przydatne linki

Od teorii do produkcji — Branchly, hosting i realizacje.

Podoba Ci się nasze podejście? Zbudujmy coś razem.

Rozpocznij konfigurację projektu