React
@junjo.io/react is the React-specific layer built on top of @junjo.io/sdk. It wires a single Junjo client through React Context and exposes hooks that consume it.
Install
npm install @junjo.io/sdk @junjo.io/reactreact is a peer dependency (^18 or ^19); the package brings no React copy of its own.
Hooks and components
| Hook / component | Description |
|---|---|
JunjoProvider | Provides a Junjo client to the subtree via context. |
useJunjo | Returns the provided client from any descendant component. |
useGroup | Snapshot + live event stream for one group’s metadata and active members, with member pagination. |
useGroups | Paginated group directory with gameId / viewer scoping; refetch-driven (no SSE subscription). |
useCan | Boolean permission check with a per-provider shared cache. |
useMembers | Paginated roster with server-side status filter and live event updates. |
useInvitations | Paginated invitation list with status filter and live event updates. |
useRoles | The group’s role definitions, kept live including per-role permission changes. |
useBans | Paginated game-wide ban list; refetch-driven (game ban events are webhook-only). |
useAuditLog | Paginated audit log with action filter; refetch-driven (no SSE subscription). |
useFriends | A user’s friend list with tag filter and viewer-perspective visibility; refetch-driven. |
useFriendRequests | Pending inbound + outbound friend requests; refetch-driven. |
useFriendSuggestions | Ranked mutual-friend suggestions; refetch-driven. |
useBlocklist | A user’s outbound blocks; refetch-driven. |
useFriendTags | A user’s private friend-list tags; refetch-driven. |
useUserVisibility | A user’s friends-list visibility setting; refetch-driven. |
useMutation | Generic mutation primitive with onMutate -> context -> onError rollback hooks for optimistic updates. |
applyOptimistic on useMembers / useInvitations / useGroup | Each hook’s result returns a snapshot + rollback helper that pairs with useMutation. |
Wiring JunjoProvider once at your app’s root is the only setup step you need. The live hooks (useGroup, useMembers, useInvitations, useRoles) share one SSE stream per group under a provider; see Shared group event streams.
Security
The provider does not make the client safe by itself; construction does. The per-game jk_ API key is a full-control secret, so a React tree needs one of two setups:
- Server context: the tree runs only in a trusted server process. Construct with
apiKey: process.env.JUNJO_API_KEY, a server-only variable. Never aNEXT_PUBLIC_/VITE_style variable: those are inlined into the client bundle at build time. - Proxy mode (browser apps, the normal case): construct with
new Junjo({ proxy: true, baseUrl: "/api/junjo" }). The browser holds no credential; your backend forwards/api/junjo/*to the Junjo API, injects the key, and enforces per-user authorization as it forwards.
Never embed a jk_ key in a client bundle; every visitor can read it and gain full control of the game. JunjoProvider + useJunjo has the full story, including a copy-paste Next.js proxy handler.