FeedbackJar integrates with React Router v7 (framework mode) via a useEffect in your app/root.tsx. React Router v7 is the successor to Remix — the same setup applies if you migrated.
# Sign up at app.feedbackjar.com
# Create a widget → copy your Widget ID // app/root.tsx
import { useEffect } from 'react';
import { Outlet } from 'react-router';
export default function App() {
useEffect(() => {
const script = document.createElement('script');
script.src = 'https://cdn.feedbackjar.com/sdk.js';
script.async = true;
script.onload = () => window.fj.init(import.meta.env.VITE_FEEDBACKJAR_ID);
document.body.appendChild(script);
return () => { if (window.fj) window.fj.destroy(); };
}, []);
return <Outlet />;
} → Initialized once in the root — it persists across every route navigation.
# .env
VITE_FEEDBACKJAR_ID=your_widget_id → React Router v7 uses Vite, so the VITE_ prefix exposes it to the client.
// app/root.tsx
import { useEffect } from 'react';
import { useLoaderData } from 'react-router';
import type { Route } from './+types/root';
export async function loader({ request }: Route.LoaderArgs) {
const user = await getUser(request); // your auth helper
return { user };
}
export default function App() {
const { user } = useLoaderData<typeof loader>();
useEffect(() => {
if (user && window.fj) {
window.fj.identify({ id: user.id, email: user.email });
}
}, [user]);
// ...
} Sign up free, grab your Widget ID, and have the feedback widget running in your React Router app in 2 minutes.