Skip to main content

Recommended: JavaScript SDK with React Hooks

For new React apps, we recommend the JavaScript SDK with React Hooks (@dynamic-labs-sdk/react-hooks) instead of the legacy React SDK documented here. The JS SDK comes with many benefits such as a much smaller bundle size and other optimizations. Use the React quickstart (JavaScript SDK) to get started.
For concepts and setup, see Access Control and Access lists. This page covers React-specific usage including scopes and the Dynamic widget. You can combine access lists with NFT and token gates.

Using your UI

You can use the useDynamicScopes hook to check for user scopes returned in the JWT.
React
import { useDynamicScopes } from '@dynamic-labs/sdk-react-core';

export const AccessControlledView = () => {
  const { hasScope, hasScopes } = useDynamicScopes();

  if (hasScopes(['beta', 'vip'])) {
    return <div>Welcome to the beta features!</div>;
  }

  if (hasScope('admin')) {
    return <div>Admin controls</div>;
  }

  return <div>Access denied</div>;
};

Customize the copy and button

You can customize the copy through props by updating the accessDeniedMessagePrimary and accessDeniedMessageSecondary.
React
<DynamicContextProvider
   settings={{
      // ...
      accessDeniedMessagePrimary: 'Your copy1',
      accessDeniedMessageSecondary: 'Your Copy2',
   }}
>
You can also return a completely custom button by passing an element to the accessDeniedButton prop. Here’s an example to link to a contact page:
React
<DynamicContextProvider
   settings={{
      // ...
      accessDeniedButton: {
         action: () => window.open(`https://www.dynamic.xyz/talk-to-us`,'_blank'),
         title: `Book a demo`
      }
   }}
>
The button should adhere to the following type:
React
type AccessDeniedCustomButton = {
   action?: () => void;
   title: string;
};
Last modified on June 25, 2026