How to restrict content by user role in WordPress
WordPress does not include a built-in setting for showing parts of a page to selected roles. You can create a custom capability and check it in your template or shortcode, but a plugin is faster for whole pages, custom post types, fields, and complex membership rules.
- 01Define what to restrict
- 02Check the existing roles
- 03Use private content where enough
- 04Add a capability-based rule
- 05Test every access path
- 06Take the fast plugin route
What you need
- Administrator access
- A staging site or recent backup
- The roles that should see the restricted content
- Access to a site-specific plugin, child theme, or code snippets tool
Define what to restrict
Decide whether you need to protect a whole page, a section inside a page, a custom post type, a taxonomy, or a downloadable file. These are different jobs. A membership or LMS site often needs several rules, such as lessons for enrolled users and resources for instructors.
Also decide what visitors should see instead: a login prompt, an upgrade message, a 404 response, or nothing. Do not rely on hiding a menu item as protection because users may still reach the URL directly.
Check the existing roles
Go to Users and confirm which roles your users actually have. WordPress includes roles such as Administrator, Editor, Author, Contributor, and Subscriber; each role receives a set of capabilities. Custom membership and LMS plugins may add their own roles.
Use a capability for the access decision rather than comparing role names wherever possible. WordPress documentation warns that checking a role directly can be unreliable, while current_user_can() is designed to test capabilities.
Use private content where enough
For a basic logged-in-only page, edit the page, open the Visibility setting, choose Private, and update it. This uses WordPress's private-content capability checks, so it can be suitable for small internal sites.
Private visibility is not a general role restriction. It does not give you a simple rule such as “Subscribers can see this lesson but Authors cannot”, and it is not a solution for hiding one section inside a public page. Test the result with a real account in each role before using it for paid or course content.
Add a capability-based rule
For a small custom implementation, add a capability such as view_members_content to each permitted role once. In site-specific code, retrieve a role with get_role() and call add_cap(); for example, $role = get_role( 'subscriber' ); if ( $role ) { $role->add_cap( 'view_members_content' ); }. Repeat this for every allowed role, and run it only during setup or activation because role changes are saved in the database.
In the template, custom block rendering code, or a shortcode callback, show the protected output only when current_user_can( 'view_members_content' ) returns true. Otherwise return your login or upgrade message. Shortcode callbacks must return their output rather than echoing it, and a custom shortcode is registered with add_shortcode().
This manual route is fine for one or two stable rules, but it becomes awkward when editors need to change access without editing code, when several roles overlap, or when you need to protect custom fields, taxonomies, lessons, or files.
Test every access path
Test while logged out, as a permitted user, and as a user in a role that should be blocked. Check the direct URL, archive pages, search results, feeds, menus, REST-powered blocks, and downloadable files. A hidden button is not enough if the original content or file URL remains public.
If a blocked user still sees the content, clear page and object caches and test with the active theme and other plugins in mind. Support cases commonly involve cached logged-in and logged-out versions, shortcode placement, or theme and plugin conflicts.
Take the fast plugin route
For complex access rules, use Toolset Access Addon. It provides a dashboard for role and user permissions across custom post types, taxonomies, and fields, with conditional content controls and support for multiple roles.
Install and activate it, then configure the roles and capabilities in its access settings. Choose this route when non-developers need to maintain the rules, or when your site has an LMS, custom content, or several membership levels. The manual capability check is genuinely fine for a small site; the plugin saves time once the rules become conditional or spread across different content types.
Let Toolset Access Addon do it
Granular role and user permissions for custom content, fields, and taxonomies; choose it for complex access rules without coding.
Sources
- wordpress.org /documentation/article/roles-and-capabilities/?utm_source=op…
- developer.wordpress.org /reference/functions/current_user_can/?utm_source=openai
- developer.wordpress.org /reference/classes/wp_role/add_cap/?utm_source=openai
- wordpress.org /support/topic/how-to-remove-content-restriction-message/?ut…
Questions
- Can WordPress restrict content by role without a plugin?
- Yes, but not through a general built-in front-end setting. WordPress can make a page private, while arbitrary role-based sections require code that checks a capability such as <code>current_user_can()</code>. You must also add that capability to the permitted roles and maintain the code yourself. For a few fixed rules this is reasonable; for membership or LMS sites, a plugin is usually easier to administer.
- Should I check a role name or a capability?
- Check a capability for the actual access decision. A role is a bundle of capabilities, and users or plugins can change those capabilities. WordPress specifically documents <code>current_user_can()</code> for capability checks and notes that checking roles directly can produce unreliable results. Create a purpose-specific capability such as <code>view_members_content</code> instead of depending on a role slug.
- Why can a blocked user still see restricted content?
- The usual causes are a cached page, testing with an account that has a higher capability, a shortcode placed outside the protected content, or a theme or plugin overriding the output. Test in a private browser window, purge page and object caches, check the direct URL, and confirm the user's current role and capabilities. Also protect files separately rather than hiding only their links.
- Does making a WordPress page private restrict it to one user role?
- No. Private visibility is based on WordPress's private-content capabilities, not a simple role picker for arbitrary front-end access. It can work for internal content, but it does not cover partial page sections, custom fields, taxonomies, or detailed membership rules. Use a capability-based implementation or an access-control plugin when the rule is more specific.
- What is the fastest way to restrict complex content?
- Use Toolset Access Addon when you need dashboard-based rules for custom post types, fields, taxonomies, or several user roles. Configure access for each content type, then test with accounts from every role. It avoids maintaining custom template and shortcode code, while the manual route remains suitable for a small number of stable rules.