Mount in root.tsx and the widget survives every navigation.
Remix's nested layouts mean a widget in root.tsx is rendered once and persists for the lifetime of the session. Works with Remix Vite and the legacy classic compiler.
npm install @usero/sdkimport { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react'
import { UseroFeedbackWidget } from '@usero/sdk/react'
export default function App() {
return (
<html lang='en'>
<head>
<Meta />
<Links />
</head>
<body>
<Outlet />
<UseroFeedbackWidget clientId='YOUR_CLIENT_ID' />
<ScrollRestoration />
<Scripts />
</body>
</html>
)
}Replace YOUR_CLIENT_ID with the id from your Usero dashboard.
Built for Remix
No special transforms or vite-plugin shims. The widget ships as standard ESM with package "exports".
The widget needs no Remix loader. It manages its own data fetching against the Usero API.
In root.tsx, the widget stays mounted through every <Outlet /> swap. Half-typed feedback survives a redirect.
No Node-only APIs in the runtime path. The widget renders identically across every Remix adapter.
Beamer injects a script that initializes after hydration, causing a layout shift. Usero is a Remix component, no shift.
FAQ
Inside <body>, after <Outlet /> and before <ScrollRestoration />. That keeps it above your route content in the DOM order.
Yes, but Remix Vite is recommended. The widget ESM bundle has package "exports", which the legacy compiler resolves correctly.
No. The trigger is a deterministic button. Server and client render the same markup.
Yes. Pass metadata={{ route: useLocation().pathname }} and the route appears on every submission in your Usero inbox.
Free tier. No credit card. Two-minute install. Cancel by deleting two lines of code.
Install guides