Skip to main content
usePermissions is a hook that calls the getPermissions method from the authProvider under the hood. It returns a query result from @tanstack/react-query.

Usage

import { usePermissions } from "@refinedev/core";

const { data: permissions } = usePermissions();

console.log(permissions);

Parameters

options
UseQueryOptions
Options to configure the query from @tanstack/react-query.
options.enabled
boolean
Enable or disable the query. By default, the query is enabled only if authProvider.getPermissions is defined.
options.retry
boolean | number
Retry configuration for failed queries.
options.onSuccess
function
Callback function to be called when the query succeeds.
options.onError
function
Callback function to be called when the query fails.
options.meta
object
Additional metadata to pass to the query.
params
Record<string, any>
Additional parameters to pass to the authProvider.getPermissions method.

Return Values

Returns a query result from @tanstack/react-query.
data
TData
The permissions data returned from authProvider.getPermissions. The shape and type of this data depends on your authProvider implementation.
isLoading
boolean
Indicates whether the query is loading.
isFetching
boolean
Indicates whether the query is fetching.
isSuccess
boolean
Indicates whether the query was successful.
isError
boolean
Indicates whether the query encountered an error.
error
any
Error object if the query failed.
refetch
function
A function to manually refetch the query.

Type Parameters

TData
any
default:"any"
Type of the permissions data returned from authProvider.getPermissions. Use this to type the permissions object.
TParams
Record<string, any>
default:"Record<string, any>"
Type of the parameters object passed to authProvider.getPermissions.

Examples

Basic Usage

import { usePermissions } from "@refinedev/core";

const Dashboard = () => {
  const { data: permissions } = usePermissions();

  return (
    <div>
      <h1>Dashboard</h1>
      {permissions?.includes("admin") && (
        <AdminPanel />
      )}
    </div>
  );
};

Conditional Rendering Based on Permissions

import { useGetIdentity, usePermissions } from "@refinedev/core";
import { Card, Avatar, Typography } from "antd";

interface IUser {
  id: string;
  name: string;
  avatar: string;
}

const DashboardPage = () => {
  const { data: identity } = useGetIdentity<IUser>();
  const { data: permissions } = usePermissions<string[]>();

  return (
    <div>
      <Card title="Identity">
        <Avatar size="large" src={identity?.avatar} />
        <Typography.Text>{identity?.name}</Typography.Text>
      </Card>

      <Card title="Permissions">
        <Typography.Text>{permissions?.join(", ")}</Typography.Text>
      </Card>
    </div>
  );
};

With Custom Parameters

import { usePermissions } from "@refinedev/core";

const ResourcePage = () => {
  const permissions = usePermissions<string[], { permissions: string[] }>({
    params: { permissions: ["admin", "editor"] },
  });

  if (permissions.isLoading) {
    return <div>Loading permissions...</div>;
  }

  return (
    <div>
      <h1>Resource Page</h1>
      <p>User permissions: {permissions.data?.join(", ")}</p>
    </div>
  );
};

Role-Based Access Control

import { usePermissions } from "@refinedev/core";

type Role = "admin" | "editor" | "viewer";

const PostsPage = () => {
  const { data: permissions, isLoading } = usePermissions<Role[]>();

  if (isLoading) {
    return <div>Checking permissions...</div>;
  }

  const canCreate = permissions?.includes("admin") || permissions?.includes("editor");
  const canEdit = permissions?.includes("admin") || permissions?.includes("editor");
  const canDelete = permissions?.includes("admin");

  return (
    <div>
      <h1>Posts</h1>
      {canCreate && <CreateButton />}
      <PostsList canEdit={canEdit} canDelete={canDelete} />
    </div>
  );
};

With Loading State

import { usePermissions } from "@refinedev/core";

const ProtectedComponent = () => {
  const { data: permissions, isLoading } = usePermissions<string[]>();

  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (!permissions?.includes("admin")) {
    return <div>You don't have permission to access this page</div>;
  }

  return <div>Admin content</div>;
};

Typed Permissions

import { usePermissions } from "@refinedev/core";

interface Permissions {
  posts: {
    create: boolean;
    edit: boolean;
    delete: boolean;
  };
  users: {
    view: boolean;
    edit: boolean;
  };
}

const App = () => {
  const { data: permissions } = usePermissions<Permissions>();

  return (
    <div>
      {permissions?.posts.create && <CreatePostButton />}
      {permissions?.users.view && <UsersLink />}
    </div>
  );
};

Disable Auto-Fetch

import { usePermissions } from "@refinedev/core";
import { useState } from "react";

const ManualPermissionsCheck = () => {
  const [enabled, setEnabled] = useState(false);

  const { data: permissions, refetch } = usePermissions({
    options: {
      enabled,
    },
  });

  return (
    <div>
      <button onClick={() => refetch()}>Check Permissions</button>
      <p>Permissions: {JSON.stringify(permissions)}</p>
    </div>
  );
};

Build docs developers (and LLMs) love