# Can

> Shows an action only to members who hold a permission key; the checks of one render share one round trip.

- Block: [access](https://bettersupabase.com/blocks/access.md)
- Kind: component
- Data: loaded on the server through the block's client
- Page: https://bettersupabase.com/recipes/can

## Install the block

```bash
npx better-supabase add access
```

## Web (Next.js)

From `apps/examples/nextjs/src/features/projects/components/task-import-action.tsx` (https://github.com/ScaleDockHQ/better-supabase/blob/main/apps/examples/nextjs/src/features/projects/components/task-import-action.tsx):

```tsx
"use client";

import { Can } from "better-supabase/blocks/access/react";

import { permissions } from "@/lib/supabase/blocks.generated";

import { TaskImportDialog } from "./task-import-dialog";

/**
 * The import button, for members with `imports.manage` in the active
 * organization. The `<Can>` checks of one render share one `my_permissions`
 * call; the import action checks the key again on the server.
 */
export function TaskImportAction({ projectId }: { projectId: string }) {
  return (
    <Can permission={permissions.imports.manage}>
      <TaskImportDialog projectId={projectId} />
    </Can>
  );
}
```

## Prompt

Paste this into a coding agent to build the recipe in your app.

### Web

```text
Build "Can" in a React web app that uses shadcn/ui components. Shows an action only to members who hold a permission key; the checks of one render share one round trip.

It uses the better-supabase `access` block (Access contract). It loads its data on the server through the block's client.

Steps:

1. If the app doesn't have the block yet, add the SQL with `npx better-supabase add access` and apply the migration.
2. The recipe needs no extra UI components.
3. The recipe needs no glue: it calls the block's client on the server.
4. Write the component. Load the data on the server with the block's client, starting from the recipe's snippet (`apps/examples/nextjs/src/features/projects/components/task-import-action.tsx`). Adapt it to the app's existing components, styling and data loading instead of copying it as is.
5. Check the result against the recipe and the block's docs: it typechecks, it reads the same block data, and it handles the loading and empty states the snippet handles.

Read the full code first:

- Recipe: https://bettersupabase.com/recipes/can.md
- Block docs: https://bettersupabase.com/docs/blocks/access
```
