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 handlowcaFormularz 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?
- Skontaktuj się z nami, zaprojektujemy formularz, scoring, CRM i hosting w jednym wdrożeniu
- Next.js Server Actions, formularze kontaktowe, techniczna warstwa submita
- Strony WWW, strony firmowe z formularzem i analityką od początku
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.
