Client-Side Usage
Import from @ops-ai/react-router-toggly/client.
RouterTogglyProvider
Hydrates automatically from loader data:
app/root.tsx
import { Outlet } from 'react-router';
import { RouterTogglyProvider } from '@ops-ai/react-router-toggly/client';
export default function App() {
return (
<RouterTogglyProvider>
<Outlet />
</RouterTogglyProvider>
);
}
With configuration
<RouterTogglyProvider
config={{
appKey: 'your-app-key',
debug: true,
}}
enableRefresh={true}
>
<Outlet />
</RouterTogglyProvider>
Specific route data
<RouterTogglyProvider routeId="root">
<Outlet />
</RouterTogglyProvider>
Feature component
Same model as the .NET <feature> tag helper: one component, negate for the off path, requirement for multi-flag gates.
import { Feature } from '@ops-ai/react-router-toggly/client';
{/* Show when enabled */}
<Feature featureKey="promo-banner">
<Promo />
</Feature>
{/* Show when disabled (negate) */}
<Feature featureKey="promo-banner" negate>
<ClassicBanner />
</Feature>
{/* Multi-flag any / all */}
<Feature featureKeys={['admin', 'ops']} requirement="any">
<AdminPanel />
</Feature>
<Feature featureKeys={['premium', 'analytics']} requirement="all">
<PremiumAnalytics />
</Feature>
| Prop | Role |
|---|---|
featureKey | Single flag |
featureKeys | Multi-flag list |
requirement | "all" (default) or "any" when using featureKeys |
negate | Invert the result (off path) — same as .NET negate="true" |
render | Optional render prop (enabled) => … when you need both branches in one place |
tip
Prefer paired <Feature> / <Feature … negate> over separate enabled/disabled component names. That matches Blazor <Feature Negate> and Razor <feature negate>.
Hooks
Use hooks when you need a boolean in JavaScript (class names, early returns, disabled controls) instead of wrapping JSX.
useFeature
import { useFeature } from '@ops-ai/react-router-toggly/client';
export function Toolbar() {
const showBeta = useFeature('beta-toolbar');
if (!showBeta) return null;
return <BetaToolbar />;
}
useFeatureFlags / useIdentity
import { useFeatureFlags, useIdentity } from '@ops-ai/react-router-toggly/client';
export function DebugPanel() {
const flags = useFeatureFlags();
const { identity } = useIdentity();
return (
<pre>
{identity ?? 'anonymous'}: {Object.keys(flags).join(', ')}
</pre>
);
}
useRefreshFlags
Imperative re-fetch of definitions (manual refresh control, recovery after network loss). Most screens do not need it — live updates go through the provider when enableRefresh is on.
import { useRefreshFlags } from '@ops-ai/react-router-toggly/client';
export function RefreshFlagsButton() {
const refresh = useRefreshFlags();
return (
<button type="button" onClick={() => refresh()}>
Refresh flags
</button>
);
}
Loader helpers
import {
useTogglyLoaderData,
useTogglyRouteLoaderData,
} from '@ops-ai/react-router-toggly/client';
const { data, toggly } = useTogglyLoaderData();
const route = useTogglyRouteLoaderData('root');