ConfettiDocs
For developers

Advanced customisation

Control when and to whom the survey appears, in code.

For finer control over when the survey shows, render the widget yourself and drive its visibility from your application code.

Scenario 1: Display the survey after a specific user action

When to use this

Use this when you want feedback immediately after a meaningful interaction. For example:

  • The user clicks "Generate a summary"
  • The user downloads a dataset
  • The user submits a form

How to configure it

import '@opengovsg/confetti/confetti.css'

import { PopoverConfetti } from '@opengovsg/confetti'

const YourComponent = () => {
  const [showConfetti, setShowConfetti] = useState(false)

  const clickHandler = useCallback(() => {
    doSomeBusinessLogic()
    setShowConfetti(true)
  }, [doSomeBusinessLogic, setShowConfetti])

  return (
    <>
      <div style={{ position: 'fixed', bottom: '1rem', right: '1rem' }}>
        <PopoverConfetti
          surveyId="<your-survey-id>"
          publishableKey="<your-publishable-key>"
          isSurveyVisible={showConfetti}
        />
      </div>
      <Button onClick={clickHandler}>Do action</Button>
    </>
  )
}

Scenario 2: Display the survey after X minutes on a page

When to use this

Use this when you want feedback from engaged users — for example, only after the user has spent one minute on the page.

How to configure it

import '@opengovsg/confetti/confetti.css'

import { PopoverConfetti, useVisibleAfterDelay } from '@opengovsg/confetti'

const YourComponent = () => {
  const { isVisible } = useVisibleAfterDelay({ delay: 60 * 1000 })

  return (
    <div style={{ position: 'fixed', bottom: '1rem', right: '1rem' }}>
      <PopoverConfetti
        surveyId="<your-survey-id>"
        publishableKey="<your-publishable-key>"
        isSurveyVisible={isVisible}
      />
    </div>
  )
}

Scenario 3: Display the survey after X page visits

When to use this

Use this when users need repeated exposure to form an opinion. For example:

  • Usability feedback
  • Showing the survey once every 10 sessions to avoid disrupting the user flow

How to configure it

import '@opengovsg/confetti/confetti.css'

import { PopoverConfetti, useVisibleAfterPageVisits } from '@opengovsg/confetti'

const YourComponent = () => {
  // If no respondent is provided, page visits are tracked per device.
  // Otherwise, they are tracked per user per device.
  const { isVisible } = useVisibleAfterPageVisits({
    visits: 10,
    respondent: '<optional-user-id>',
  })

  return (
    <div style={{ position: 'fixed', bottom: '1rem', right: '1rem' }}>
      <PopoverConfetti
        surveyId="<your-survey-id>"
        publishableKey="<your-publishable-key>"
        isSurveyVisible={isVisible}
      />
    </div>
  )
}

Scenario 4: Display the survey to specific users only

When to use this

Use this when feedback is only relevant to certain users. For example:

  • Role-specific features — show the survey only to specific user types (e.g. admin, member)
  • Onboarding workflows — show the survey only once per user ID

How to configure it

import '@opengovsg/confetti/confetti.css'

import { PopoverConfetti } from '@opengovsg/confetti'

const YourComponent = () => {
  // Get the user role from your server or session.
  const { role, id: userId } = useUser()

  return (
    <div style={{ position: 'fixed', bottom: '1rem', right: '1rem' }}>
      <PopoverConfetti
        surveyId="<your-survey-id>"
        publishableKey="<your-publishable-key>"
        respondent={userId}
        // Show the survey only if the user's role is "superuser" and they
        // have not responded to this survey before.
        isSurveyVisible={({ lastRespondedAt }) =>
          role === 'superuser' && !lastRespondedAt
        }
      />
    </div>
  )
}

On this page