Skip to main content
Add the SeggWat feedback button to your React application in minutes. Works seamlessly with Create React App, Next.js, Vite, and other React frameworks.

Quick Setup

The SeggWat button works with any React setup. Choose the method that fits your project:
Add the script to your public/index.html file:
public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>React App</title>

    <!-- SeggWat Feedback Button -->
    <script defer
      src="https://seggwat.com/static/widgets/v1/seggwat-feedback.js"
      data-project-key="YOUR_PROJECT_KEY"
      data-button-color="#61dafb">
    </script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
The #61dafb color matches React’s official branding!

Version Tracking

Track feedback against specific releases by adding the data-version attribute:
Import version directly from package.json:
app/layout.tsx
import Script from 'next/script'
import packageJson from '../package.json'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <head>
        <Script
          src="https://seggwat.com/static/widgets/v1/seggwat-feedback.js"
          data-project-key={process.env.NEXT_PUBLIC_SEGGWAT_PROJECT_KEY}
          data-version={packageJson.version}
          strategy="lazyOnload"
        />
      </head>
      <body>{children}</body>
    </html>
  )
}
Every feedback submission will include your current version from package.json.

Version Tracking Guide

Learn more about automated version injection and CI/CD integration

Dynamic Updates

Update the feedback button appearance dynamically using the global API:
components/FeedbackSettings.tsx
import { useState } from 'react'

export function FeedbackSettings() {
  const [color, setColor] = useState('#2563eb')

  const updateButtonColor = (newColor: string) => {
    setColor(newColor)

    // Update SeggWat button appearance
    if (window.SeggwattFeedback) {
      window.SeggwattFeedback.updateAppearance({
        color: newColor
      })
    }
  }

  return (
    <div>
      <h3>Customize Feedback Button</h3>
      <button onClick={() => updateButtonColor('#ef4444')}>
        Red Theme
      </button>
      <button onClick={() => updateButtonColor('#10b981')}>
        Green Theme
      </button>
      <button onClick={() => updateButtonColor('#3b82f6')}>
        Blue Theme
      </button>
    </div>
  )
}

TypeScript Support

Add type definitions for the SeggWat API:
types/seggwat.d.ts
interface SeggwatFeedback {
  updateAppearance(options: {
    color?: string
    position?: 'bottom-right' | 'right-side' | 'icon-only'
    language?: 'en' | 'de' | 'sv'
  }): Promise<void>
  container: HTMLButtonElement
}

interface Window {
  SeggwattFeedback?: SeggwatFeedback
}
Now you get full autocomplete:
// TypeScript knows about SeggwattFeedback!
window.SeggwattFeedback?.updateAppearance({
  color: '#ef4444',
  position: 'bottom-right',
  language: 'de'
})

React Router Integration

The feedback button works seamlessly with React Router - no special configuration needed:
App.tsx
import { BrowserRouter, Routes, Route } from 'react-router-dom'

function App() {
  return (
    <BrowserRouter>
      {/* Button appears on all routes */}
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  )
}
The feedback button automatically captures the current route path when users submit feedback, helping you understand which pages need improvements.

Environment Variables

Use environment variables to manage your project key across environments:
// .env.production
REACT_APP_SEGGWAT_PROJECT_KEY=your-production-key

// .env.development
REACT_APP_SEGGWAT_PROJECT_KEY=your-dev-key

// In your component
const projectKey = process.env.REACT_APP_SEGGWAT_PROJECT_KEY || ''
Then use in your component:
<FeedbackButton projectKey={projectKey} />

Advanced Examples

Conditional Rendering

Show the feedback button only on specific routes or for certain users:
App.tsx
import { useLocation } from 'react-router-dom'
import { FeedbackButton } from './components/FeedbackButton'

function App() {
  const location = useLocation()
  const isProductionRoute = location.pathname.startsWith('/app')

  return (
    <>
      {/* Only show on production routes */}
      {isProductionRoute && (
        <FeedbackButton
          projectKey="YOUR_PROJECT_KEY"
          buttonColor="#10b981"
        />
      )}

      {/* Your app content */}
    </>
  )
}

Theme Integration

Sync the feedback button with your app’s theme:
App.tsx
import { useState, useEffect } from 'react'
import { FeedbackButton } from './components/FeedbackButton'

function App() {
  const [theme, setTheme] = useState<'light' | 'dark'>('light')

  useEffect(() => {
    // Update button color when theme changes
    const color = theme === 'dark' ? '#ffffff' : '#000000'

    window.SeggwattFeedback?.updateAppearance({ color })
  }, [theme])

  return (
    <div className={theme}>
      <FeedbackButton
        projectKey="YOUR_PROJECT_KEY"
        buttonColor={theme === 'dark' ? '#ffffff' : '#000000'}
      />

      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        Toggle Theme
      </button>
    </div>
  )
}

Custom Hook

Create a custom hook for easier integration:
hooks/useSeggwat.ts
import { useEffect, useState } from 'react'

interface UseSeggwatOptions {
  projectKey: string
  buttonColor?: string
  buttonPosition?: 'bottom-right' | 'right-side' | 'icon-only'
  language?: 'en' | 'de' | 'sv'
  version?: string
}

export function useSeggwat({
  projectKey,
  buttonColor = '#2563eb',
  buttonPosition = 'bottom-right',
  language = 'en',
  version,
}: UseSeggwatOptions) {
  const [isLoaded, setIsLoaded] = useState(false)

  useEffect(() => {
    const script = document.createElement('script')
    script.src = 'https://seggwat.com/static/widgets/v1/seggwat-feedback.js'
    script.defer = true
    script.setAttribute('data-project-key', projectKey)
    script.setAttribute('data-button-color', buttonColor)
    script.setAttribute('data-button-position', buttonPosition)
    script.setAttribute('data-language', language)
    if (version) {
      script.setAttribute('data-version', version)
    }

    script.onload = () => setIsLoaded(true)
    document.head.appendChild(script)

    return () => {
      document.head.removeChild(script)
      document.getElementById('seggwat-feedback-button')?.remove()
      document.getElementById('seggwat-feedback-modal-overlay')?.remove()
    }
  }, [projectKey, buttonColor, buttonPosition, language, version])

  const updateAppearance = (options: {
    color?: string
    position?: 'bottom-right' | 'right-side' | 'icon-only'
    language?: 'en' | 'de' | 'sv'
  }) => {
    window.SeggwattFeedback?.updateAppearance(options)
  }

  return { isLoaded, updateAppearance }
}
Usage:
App.tsx
import { useSeggwat } from './hooks/useSeggwat'
import packageJson from '../package.json'

function App() {
  const { isLoaded, updateAppearance } = useSeggwat({
    projectKey: 'YOUR_PROJECT_KEY',
    buttonColor: '#61dafb',
    version: packageJson.version,
  })

  return (
    <div>
      {isLoaded && <p>Feedback button loaded!</p>}

      <button onClick={() => updateAppearance({ color: '#ef4444' })}>
        Change to Red
      </button>
    </div>
  )
}

React Native

The SeggWat feedback button is designed for web applications. For React Native mobile apps, consider using the API directly:
import { useState } from 'react'
import { View, TextInput, Button, Alert } from 'react-native'

export function FeedbackForm() {
  const [message, setMessage] = useState('')

  const submitFeedback = async () => {
    try {
      const response = await fetch('https://seggwat.com/api/v1/feedback/submit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          project_key: 'YOUR_PROJECT_KEY',
          message,
          path: 'mobile-app',
        }),
      })

      if (response.ok) {
        Alert.alert('Success', 'Thank you for your feedback!')
        setMessage('')
      }
    } catch (error) {
      Alert.alert('Error', 'Failed to send feedback')
    }
  }

  return (
    <View>
      <TextInput
        value={message}
        onChangeText={setMessage}
        placeholder="Share your feedback..."
        multiline
      />
      <Button title="Send Feedback" onPress={submitFeedback} />
    </View>
  )
}

API Reference

Learn more about the SeggWat REST API

Troubleshooting

Common solutions:
  • Ensure the script is in the <head> section, not inside React components
  • Check the browser console for JavaScript errors
  • Verify your project key is correct (no quotes or extra characters)
  • For Create React App, make sure you’re editing public/index.html, not src/index.html
  • Clear build cache: rm -rf node_modules/.cache and restart dev server
This usually means the script is being removed/re-added. Solutions:
  • Add the script to your HTML file instead of a component
  • For Next.js, use the Script component in _app.tsx or root layout
  • Ensure cleanup functions in useEffect aren’t removing the button prematurely
Add type definitions:
interface Window {
  SeggwattFeedback?: {
    updateAppearance(options: any): void
    container: HTMLButtonElement
  }
}
Place this in a types/global.d.ts file or at the top of your component.
The SeggWat button works only in the browser. To avoid SSR issues:
  • Use Next.js Script component with strategy="lazyOnload"
  • Add checks: if (typeof window !== 'undefined')
  • Don’t call window.SeggwattFeedback during server-side rendering
If your app uses CSP headers, allow SeggWat scripts:
script-src 'self' https://seggwat.com;
connect-src 'self' https://seggwat.com;
style-src 'self' https://seggwat.com 'unsafe-inline';
For Next.js, add to next.config.js:
const securityHeaders = [
  {
    key: 'Content-Security-Policy',
    value: "script-src 'self' https://seggwat.com; ..."
  }
]

Best Practices

Load asynchronously

Use defer or async attributes to avoid blocking page render. Next.js’s Script component handles this automatically.

Environment-based keys

Use different project keys for development, staging, and production to keep feedback organized.

Add to root layout

Place the script in your app’s root layout or HTML file so it appears on all routes without re-mounting.

Type safety

Add TypeScript definitions for window.SeggwattFeedback to get autocomplete and type checking.

Example Projects

Minimal Create React App

npx create-react-app my-app
cd my-app
Edit public/index.html:
<script defer
  src="https://seggwat.com/static/widgets/v1/seggwat-feedback.js"
  data-project-key="YOUR_PROJECT_KEY">
</script>
npm start

Minimal Next.js App

npx create-next-app@latest my-app
cd my-app
Edit app/layout.tsx:
import Script from 'next/script'

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        <Script
          src="https://seggwat.com/static/widgets/v1/seggwat-feedback.js"
          data-project-key="YOUR_PROJECT_KEY"
          strategy="lazyOnload"
        />
      </head>
      <body>{children}</body>
    </html>
  )
}
npm run dev

Next Steps


Need help with your React integration? Reach out at [email protected] or check our full documentation.