React Installation
Add Simple Commenter to your React application. This guide covers Create React App, Vite, and custom React setups.
Important: The domain in your script must exactly match the domain you registered in your Simple Commenter dashboard. If they don't match, the widget won't load.
Method 1: index.html (Simplest)
Add the script to your HTML file. This works for any React setup.
Create React App
Edit public/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My App</title>
</head>
<body>
<div id="root"></div>
<!-- Add Simple Commenter before closing body -->
<script
src="https://simplecommenter.com/js/comments.min.js"
data-domain="your-domain.com"
defer
></script>
</body>
</html>
Vite
Edit index.html in your project root:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
<!-- Add Simple Commenter -->
<script
src="https://simplecommenter.com/js/comments.min.js"
data-domain="your-domain.com"
defer
></script>
</body>
</html>
Replace your-domain.com with your actual domain from the Simple Commenter dashboard.
Method 2: React Component
Create a component that loads the script dynamically. Useful for conditional loading.
// src/components/SimpleCommenter.jsx
import { useEffect } from "react";
export default function SimpleCommenter() {
useEffect(() => {
// Check if script already exists
if (document.querySelector('script[data-domain]')) return;
const script = document.createElement("script");
script.src = "https://simplecommenter.com/js/comments.min.js";
script.dataset.domain = "your-domain.com";
script.defer = true;
document.body.appendChild(script);
return () => {
// Cleanup on unmount (optional)
const existingScript = document.querySelector('script[data-domain]');
if (existingScript) {
document.body.removeChild(existingScript);
}
};
}, []);
return null;
}
Then add it to your app:
// src/App.jsx
import SimpleCommenter from "./components/SimpleCommenter";
function App() {
return (
<>
{/* Your app content */}
<SimpleCommenter />
</>
);
}
Method 3: Custom Hook
For more flexibility:
// src/hooks/useSimpleCommenter.js
import { useEffect } from "react";
export function useSimpleCommenter(domain) {
useEffect(() => {
if (!domain) return;
if (document.querySelector('script[data-simple-commenter]')) return;
const script = document.createElement("script");
script.src = "https://simplecommenter.com/js/comments.min.js";
script.dataset.domain = domain;
script.dataset.simpleCommenter = "true";
script.defer = true;
document.body.appendChild(script);
return () => {
const el = document.querySelector('script[data-simple-commenter]');
if (el) document.body.removeChild(el);
};
}, [domain]);
}
Usage:
// src/App.jsx
import { useSimpleCommenter } from "./hooks/useSimpleCommenter";
function App() {
useSimpleCommenter("your-domain.com");
return <div>Your app</div>;
}
Environment Variables
Use environment variables for the domain:
// .env
REACT_APP_SC_DOMAIN=your-domain.com // CRA
VITE_SC_DOMAIN=your-domain.com // Vite
// In your component
const domain = process.env.REACT_APP_SC_DOMAIN; // CRA
const domain = import.meta.env.VITE_SC_DOMAIN; // Vite
Conditional Loading
Only load on certain routes:
import { useLocation } from "react-router-dom";
import { useEffect } from "react";
function App() {
const location = useLocation();
useEffect(() => {
// Only load on specific paths
const enabledPaths = ["/", "/about", "/contact"];
if (!enabledPaths.includes(location.pathname)) return;
// Load script...
}, [location]);
}
Verifying Installation
- Run your development server (
npm startornpm run dev) - Open your app in the browser
- Look for the feedback widget button
- Check browser console (F12) for errors
Troubleshooting
Widget not appearing
- Check the domain matches your dashboard settings
- Verify the script isn't being blocked by browser extensions
- Look for JavaScript errors in the console
- Ensure the script is actually in the DOM (inspect Elements)
Widget appears multiple times
- The component is mounting multiple times
- Add a check for existing script before creating a new one
- Use the cleanup function in useEffect
Hot reload issues
During development with hot reload, the widget may need a full page refresh to appear correctly after code changes.
React Router / Client-side routing
The widget persists across route changes. It loads once and stays active throughout the session.
Need help? Contact support.