React Client Plugin


The React Client Plugin provides a set of React components and hooks for working with the Kilpi client in a React application.

Ensure you have setup KilpiClient for using Kilpi on the client.


Installation

Install the plugin with your package manager of choice.

Apply the plugin in your Kilpi configuration as follows.

kilpi.ts
import { createKilpiClient } from "@kilpi/client";
import { ReactClientComponentPlugin } from "@kilpi/react-client";
export const KilpiClient = createKilpiClient({
// ...
plugins: [ReactClientComponentPlugin()]
})

Components and hooks

Use the Kilpi.ReactClient.createComponents function (provided by the plugin) to create React client component and hook bindings for working with the KilpiClient.

kilpi.components.ts
export const {
// Utility hooks that wrap KilpiClient methods
useIsAuthorized,
useSubject,
// Utility component that wraps useIsAuthorized
ClientAccess,
} = KilpiClient.ReactClient.createComponents();

useIsAuthorized()

useIsAuthorized() fetches an authorization decision from the Kilpi server using KilpiClient.fetchIsAuthorized().

export function DeleteCommentButton({ comment, onDelete }) {
const {
isAuthorized, // boolean (when "success"), null (otherwise)
status, // "idle" | "loading" | "error" | "success"
error, // unknown (when "error"), null (otherwise)
isLoading, // boolean, true when status is "loading"
isError, // boolean, true when status is "error"
isSuccess, // boolean, true when status is "success"
isIdle, // boolean, true when status is "idle"
} = useIsAuthorized("comments:delete", comment);
return (
<button disabled={!isAuthorized} onClick={onDelete}>
Delete comment
</button>
);
}

useSubject()

Fetches the current subject from the Kilpi server using KilpiClient.fetchSubject().

export function User() {
const {
subject, // Inferred subject type (when "success"), null (otherwise)
status, // "idle" | "loading" | "error" | "success"
error, // unknown (when "error"), null (otherwise)
isLoading, // boolean, true when status is "loading"
isError, // boolean, true when status is "error"
isSuccess, // boolean, true when status is "success"
isIdle, // boolean, true when status is "idle"
} = useSubject();
return <p>Signed in as {subject?.name}</p>;
}

<ClientAccess />

Similar to the <Access /> React Server Component, <ClientAccess /> is used to show or hide components based on the user’s authorizations.

<ClientAccess /> uses the useIsAuthorized() hook under the hood.

async function Component({ comment }) {
return (
<div>
<p>{comment.content}</p>
<Access
to="comments:delete"
// Required only if policy takes in a resource
on={comment}
// Optional fallback UIs
Loading={<p>Loading...</p>}
Unauthorized={<p>Unauthorized</p>}
Error={<p>Error</p>}
>
<button>Delete</button>
</Access>
</div>
);
}