Skip to content

React Runtime Environment Variables — useRep() Hooks

Terminal window
npm install @rep-protocol/react @rep-protocol/sdk
import { useRep, useRepSecure } from '@rep-protocol/react';
function App() {
// PUBLIC tier — synchronous, no loading state
const apiUrl = useRep('API_URL', 'http://localhost:3000');
const flags = useRep('FEATURE_FLAGS', '').split(',');
// SENSITIVE tier — async, renders null until resolved
const { value: analyticsKey, loading, error } = useRepSecure('ANALYTICS_KEY');
if (loading) return <span>Loading...</span>;
if (error) return <span>Config error: {error.message}</span>;
return (
<div>
<p>API: {apiUrl}</p>
<p>Analytics: {analyticsKey}</p>
</div>
);
}

Before:

src/config.ts
export const API_URL = import.meta.env.VITE_API_URL;
export const FEATURE_FLAGS = import.meta.env.VITE_FEATURE_FLAGS?.split(',') ?? [];

After:

src/config.ts
import { rep } from '@rep-protocol/sdk';
export const API_URL = rep.get('API_URL', 'http://localhost:3000');
export const FEATURE_FLAGS = rep.get('FEATURE_FLAGS', '')?.split(',').filter(Boolean) ?? [];

Or use the codemod for automated migration:

Terminal window
npx @rep-protocol/codemod --framework vite src/

Reads a PUBLIC tier variable. Synchronous — no loading state, no Suspense.

const value = useRep('API_URL'); // string | undefined
const value = useRep('API_URL', 'fallback'); // string (never undefined)
  • Returns the value from the injected payload immediately
  • Returns defaultValue (or undefined) if the variable is not present
  • Automatically re-renders when the variable changes via hot reload
  • Unsubscribes on unmount

Reads a SENSITIVE tier variable. Async — fetches a session key on first call.

const { value, loading, error } = useRepSecure('ANALYTICS_KEY');
// value: string | null — null until resolved
// loading: boolean — true while fetching
// error: Error | null — set if fetch or decryption fails
  • Starts with { value: null, loading: true, error: null }
  • The decrypted value is cached by the SDK for the page lifetime
  • Re-fetches if the key prop changes

Both hooks subscribe to the gateway’s SSE stream when --hot-reload is enabled. Components re-render automatically when config changes. If hot reload is not available, hooks still work — they just won’t update after initial render.

Without the gateway running, useRep() returns undefined. Three approaches:

Terminal window
npm install -D @rep-protocol/vite
vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { repPlugin } from '@rep-protocol/vite';
export default defineConfig({
plugins: [react(), repPlugin()],
});

The plugin reads .env.local and injects the REP payload during vite dev — no gateway needed. Just run npm run dev as normal. Using Next.js instead? See the Next.js plugin reference — same idea, RepScript instead of repPlugin(). Full option list: Vite plugin reference.

  • React >= 16.8 (hooks support)
  • @rep-protocol/sdk as a peer dependency

For the full API reference, see React Adapter Reference.