Installation

Fountain is a self-contained inline feedback system that works with React and any other framework (Vue, Svelte, Angular, vanilla JS). Choose the installation method that matches your stack.

For React Projects

Install via npm (Recommended)

Install from GitHub Packages:

npm install @bankrate/fountain

Or with pnpm:

pnpm add @bankrate/fountain

GitHub Packages Setup: The @bankrate scope is published to GitHub's package registry (not public npm). You'll need to:

  1. Create a GitHub Personal Access Token with read:packages scope
  2. Configure your .npmrc file:
    @bankrate:registry=https://npm.pkg.github.com
    //npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN
    
  3. See GitHub's documentation for details

Then add to your next.config.mjs:

const nextConfig = {
  transpilePackages: ["@bankrate/fountain"],
}
export default nextConfig

Import in your app:

// In your root layout
import "@bankrate/fountain/fountain.css"

// In your components
import {
  FeedbackProvider,
  FeedbackWidget,
  useFeedbackTrigger,
  surveyTemplates,
} from "@bankrate/fountain"

Important: You must explicitly import the CSS file in your app's root layout or global CSS file.

For Non-React Projects (Vue, Svelte, Angular, Vanilla JS)

Use the framework-agnostic embed version that bundles React internally and exposes a simple JavaScript API.

Option 1: CDN (Easiest)

Load from the CDN and initialize:

<!-- Load the embed bundle -->
<script src="https://fountain.bankrate.com/api/fountain-package/embed"></script>

<!-- Initialize Fountain -->
<script>
  window.Fountain.init({
    containerId: 'feedback-root',
    survey: window.Fountain.templates.nps,
    apiEndpoint: 'https://your-api.com/feedback',
    // iterableEndpoint: 'https://yourapp.com/api/iterable/subscribe', // optional: full URL for email → Iterable
  });
</script>

<!-- Mount point -->
<div id="feedback-root"></div>

Option 2: npm Install

npm install @bankrate/fountain

Note: Requires GitHub Packages authentication. See the React installation section above for setup details.

Then in your JavaScript:

import '@bankrate/fountain/embed';

window.Fountain.init({
  containerId: 'feedback-root',
  survey: window.Fountain.templates.nps,
  apiEndpoint: 'https://your-api.com/feedback',
  // iterableEndpoint: 'https://yourapp.com/api/iterable/subscribe', // optional
});

Available Templates

The embed version exposes all templates via window.Fountain.templates:

window.Fountain.templates.nps
window.Fountain.templates.csat
window.Fountain.templates.rating
window.Fountain.templates.thumbs
window.Fountain.templates.emoji
window.Fountain.templates.text
window.Fountain.templates.multiChoice
window.Fountain.templates.scale

Custom Surveys

You can also define custom surveys:

window.Fountain.init({
  containerId: 'feedback-root',
  survey: {
    id: 'custom-survey',
    title: 'How was your experience?',
    questions: [
      {
        id: 'q1',
        type: 'thumbs',
        text: 'Was this helpful?'
      }
    ]
  },
  apiEndpoint: 'https://your-api.com/feedback',
  // iterableEndpoint: 'https://yourapp.com/api/iterable/subscribe', // optional
});

Style Isolation

Fountain ships its own scoped CSS file (fountain.css) that defines all brand colors and animations as CSS custom properties under a .fountain class. This means:

  • No dependency on the host app's Tailwind color config -- Fountain brings its own colors
  • No dependency on shadcn/ui or tailwindcss-animate -- animations are self-contained
  • No style leaking -- all color variables are scoped under the .fountain wrapper class
  • The only Tailwind classes used are standard layout utilities (flex, p-4, rounded-lg, etc.) which are stable across all Tailwind versions

Peer Dependencies

Your host project needs these (most React + Tailwind projects already have them):

react >= 18
tailwindcss >= 3
clsx >= 2
tailwind-merge >= 2
lucide-react >= 0.400.0

Fountain Documentation

Welcome to the Fountain feedback widget documentation. Choose a topic below to get started.

Getting Started

Core Concepts

Advanced

  • Custom Surveys - Build your own surveys from scratch
  • Configuration - API integration, CDP setup, iterableEndpoint (full URL for server-side Iterable subscribe), lifecycle callbacks, and advanced options

Quick Reference

Minimal Setup

import { FeedbackProvider, FeedbackWidget } from "@bankrate/fountain"

export default function Layout({ children }) {
  return (
    <FeedbackProvider>
      {children}
      <FeedbackWidget />
    </FeedbackProvider>
  )
}

Show a Survey

import { useFeedback, surveyTemplates } from "@bankrate/fountain"

function MyComponent() {
  const { showSurvey } = useFeedback()
  
  return (
    <button onClick={() => showSurvey(surveyTemplates.nps)}>
      Give Feedback
    </button>
  )
}

Automatic Trigger

import { useFeedbackTrigger, surveyTemplates } from "@bankrate/fountain"

function MyPage() {
  useFeedbackTrigger({
    survey: {
      ...surveyTemplates.quickMood,
      trigger: { type: "scroll-depth", scrollDepth: 50 }
    },
    enabled: true
  })
  
  return <div>Your content</div>
}

Need Help?