NPS Prompt

Survey asking likelihood of recommending the product.

How likely are you to recommend us to a friend or colleague?

Not likelyVery likely

Takes about 10 seconds

html

<div class="nps" data-scale="numeric" style="--accent:#E8A020;">
  
  <button type="button" class="nps__close" aria-label="Dismiss survey">×</button>
  
  <span class="nps__accent" aria-hidden="true"></span>
  <p class="nps__question">How likely are you to recommend us to a friend or colleague?</p>
  <div class="nps__scale nps__scale--numeric">
    <button type="button" class="nps__num">0</button><button type="button" class="nps__num">1</button><button type="button" class="nps__num">2</button><button type="button" class="nps__num">3</button><button type="button" class="nps__num">4</button><button type="button" class="nps__num">5</button><button type="button" class="nps__num">6</button><button type="button" class="nps__num">7</button><button type="button" class="nps__num">8</button><button type="button" class="nps__num">9</button><button type="button" class="nps__num">10</button>
  </div>
  <div class="nps__scale nps__scale--emoji">
    <button type="button" class="nps__emoji" aria-label="Not likely">😕</button><button type="button" class="nps__emoji" aria-label="Neutral">😐</button><button type="button" class="nps__emoji" aria-label="Likely">🙂</button><button type="button" class="nps__emoji" aria-label="Very likely">😍</button>
  </div>
  <div class="nps__scale nps__scale--stars">
    <button type="button" class="nps__star" aria-label="1 star">★</button><button type="button" class="nps__star" aria-label="2 stars">★</button><button type="button" class="nps__star" aria-label="3 stars">★</button><button type="button" class="nps__star" aria-label="4 stars">★</button><button type="button" class="nps__star" aria-label="5 stars">★</button>
  </div>
  <div class="nps__labels"><span>Not likely</span><span>Very likely</span></div>
  <p class="nps__footnote">Takes about 10 seconds</p>
</div>
<style>
.nps { position: relative; font: 16px/1.5 system-ui, sans-serif; color: #241430; background: #FAF7F2; padding: 20px 22px; max-width: 380px; border-radius: 14px; border: 1px solid #24143018; }
.nps__close { position: absolute; top: 10px; right: 10px; width: 26px; height: 26px; border: none; background: transparent; color: #24143080; font-size: 16px; cursor: pointer; border-radius: 6px; }
.nps__close:hover, .nps__close:focus-visible { background: #24143012; color: #241430; }
.nps__accent { display: block; width: 36px; height: 3px; border-radius: 2px; margin-bottom: 10px; background: var(--accent); }
.nps__question { margin: 0 0 14px; font-weight: 600; font-size: 15px; padding-right: 20px; }
.nps__scale { display: none; gap: 6px; flex-wrap: wrap; }
.nps[data-scale="numeric"] .nps__scale--numeric,
.nps[data-scale="emoji"] .nps__scale--emoji,
.nps[data-scale="stars"] .nps__scale--stars { display: flex; }
.nps__num, .nps__emoji, .nps__star { border: 1.5px solid #24143025; background: #fff; border-radius: 8px; width: 30px; height: 30px; font-size: 13px; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.nps__emoji, .nps__star { font-size: 17px; border-radius: 10px; width: 36px; height: 36px; }
.nps__star { color: #24143035; border: none; background: none; }
.nps__num:hover, .nps__emoji:hover, .nps__star:hover,
.nps__num:focus-visible, .nps__emoji:focus-visible, .nps__star:focus-visible { border-color: var(--accent); color: var(--accent); outline: none; }
.nps__labels { display: flex; justify-content: space-between; font-size: 11px; color: #24143080; margin-top: 6px; }
.nps[data-scale="emoji"] .nps__labels, .nps[data-scale="stars"] .nps__labels { display: none; }
.nps__footnote { margin: 14px 0 0; font-size: 11.5px; color: #24143080; }
</style>

tailwind

<div class="nps-tw relative max-w-sm p-5 rounded-2xl border border-[#24143018] bg-[#FAF7F2] text-[#241430] font-sans" data-scale="numeric" style="--accent:#E8A020">
  
  <button type="button" class="absolute top-2.5 right-2.5 w-6.5 h-6.5 rounded-md text-[#24143080] hover:bg-[#24143012] hover:text-[#241430]" aria-label="Dismiss survey">×</button>
  
  <span class="block w-9 h-[3px] rounded-full mb-2.5" style="background:#E8A020" aria-hidden="true"></span>
  <p class="m-0 mb-3.5 pr-5 font-semibold text-[15px]">How likely are you to recommend us to a friend or colleague?</p>
  <div class="nps-tw__scale nps-tw__scale--numeric hidden flex-wrap gap-1.5">
    <button type="button" class="w-[30px] h-[30px] rounded-lg border-[1.5px] border-[#24143025] bg-white text-xs">0</button>
    <button type="button" class="w-[30px] h-[30px] rounded-lg border-[1.5px] border-[#24143025] bg-white text-xs">1</button>
    <button type="button" class="w-[30px] h-[30px] rounded-lg border-[1.5px] border-[#24143025] bg-white text-xs">2</button>
    <button type="button" class="w-[30px] h-[30px] rounded-lg border-[1.5px] border-[#24143025] bg-white text-xs">3</button>
    <button type="button" class="w-[30px] h-[30px] rounded-lg border-[1.5px] border-[#24143025] bg-white text-xs">4</button>
    <button type="button" class="w-[30px] h-[30px] rounded-lg border-[1.5px] border-[#24143025] bg-white text-xs">5</button>
    <button type="button" class="w-[30px] h-[30px] rounded-lg border-[1.5px] border-[#24143025] bg-white text-xs">6</button>
    <button type="button" class="w-[30px] h-[30px] rounded-lg border-[1.5px] border-[#24143025] bg-white text-xs">7</button>
    <button type="button" class="w-[30px] h-[30px] rounded-lg border-[1.5px] border-[#24143025] bg-white text-xs">8</button>
    <button type="button" class="w-[30px] h-[30px] rounded-lg border-[1.5px] border-[#24143025] bg-white text-xs">9</button>
    <button type="button" class="w-[30px] h-[30px] rounded-lg border-[1.5px] border-[#24143025] bg-white text-xs">10</button>
  </div>
  <div class="nps-tw__scale nps-tw__scale--emoji hidden flex-wrap gap-1.5">
    <button type="button" class="w-9 h-9 rounded-[10px] text-lg" aria-label="Not likely">😕</button>
    <button type="button" class="w-9 h-9 rounded-[10px] text-lg" aria-label="Neutral">😐</button>
    <button type="button" class="w-9 h-9 rounded-[10px] text-lg" aria-label="Likely">🙂</button>
    <button type="button" class="w-9 h-9 rounded-[10px] text-lg" aria-label="Very likely">😍</button>
  </div>
  <div class="nps-tw__scale nps-tw__scale--stars hidden flex-wrap gap-1.5 text-[#24143035] text-lg">
    <button type="button" aria-label="1 star">★</button><button type="button" aria-label="2 stars">★</button><button type="button" aria-label="3 stars">★</button><button type="button" aria-label="4 stars">★</button><button type="button" aria-label="5 stars">★</button>
  </div>
  <p class="mt-3.5 mb-0 text-[11.5px] text-[#24143080]">Takes about 10 seconds</p>
</div>
<style>
.nps-tw[data-scale="numeric"] .nps-tw__scale--numeric,
.nps-tw[data-scale="emoji"] .nps-tw__scale--emoji,
.nps-tw[data-scale="stars"] .nps-tw__scale--stars { display: flex; }
</style>

react

export function NpsPrompt({
  question = "How likely are you to recommend us to a friend or colleague?",
  scaleStyle = "numeric",
  accent = "#E8A020",
  footnote = "Takes about 10 seconds",
  dismissible = true,
}) {
  const scales = {
    numeric: (
      <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
        {Array.from({ length: 11 }, (_, i) => (
          <button key={i} type="button" style={{ width: 30, height: 30, borderRadius: 8, border: "1.5px solid #24143025", background: "#fff", fontSize: 13 }}>{i}</button>
        ))}
      </div>
    ),
    emoji: (
      <div style={{ display: "flex", gap: 8 }}>
        {["😕", "😐", "🙂", "😍"].map((e, i) => (
          <button key={i} type="button" aria-label="rating" style={{ width: 36, height: 36, borderRadius: 10, border: "none", background: "none", fontSize: 18 }}>{e}</button>
        ))}
      </div>
    ),
    stars: (
      <div style={{ display: "flex", gap: 6, color: "#24143035", fontSize: 18 }}>
        {[1, 2, 3, 4, 5].map((n) => (
          <button key={n} type="button" aria-label={n + " stars"} style={{ border: "none", background: "none", color: "inherit" }}>★</button>
        ))}
      </div>
    ),
  };
  return (
    <div style={{ position: "relative", font: "16px/1.5 system-ui, sans-serif", color: "#241430", background: "#FAF7F2", padding: "20px 22px", maxWidth: 380, borderRadius: 14, border: "1px solid #24143018" }}>
      {dismissible && (
        <button type="button" aria-label="Dismiss survey" style={{ position: "absolute", top: 10, right: 10, width: 26, height: 26, border: "none", background: "transparent", color: "#24143080", fontSize: 16, borderRadius: 6, cursor: "pointer" }}>×</button>
      )}
      <span aria-hidden="true" style={{ display: "block", width: 36, height: 3, borderRadius: 2, marginBottom: 10, background: accent }} />
      <p style={{ margin: "0 0 14px", fontWeight: 600, fontSize: 15, paddingRight: 20 }}>{question}</p>
      {scales[scaleStyle] ?? scales.numeric}
      <p style={{ margin: "14px 0 0", fontSize: 11.5, color: "#24143080" }}>{footnote}</p>
    </div>
  );
}