How to Require Login to View a Page in WordPress (4 Easy Ways)

Sometimes you need a page that’s not for everyone—client portals, course lessons, pricing sheets for partners, internal SOPs, or a private download area. WordPress gives you a few simple ways to lock a page behind a login, from zero-code toggles to developer-friendly snippets.

Below are four clean approaches—pick the one that matches your setup and tech comfort. I’ll also flag caching gotchas, SEO considerations, and menu behavior so things don’t leak accidentally.


Quick menu of options

  • Fastest (no plugin): Use WordPress’s built-in Password Protect or Private visibility
  • Granular control (no code): Use a content restriction / membership plugin
  • Template or URL-based lock (with code): Add a redirect-if-not-logged-in snippet
  • Whole section lockdown: Protect categories, custom post types, or children pages with rules

Method 1 — Built-in WordPress protections (no plugin)

Option A: Password-protect a single page

Great when you want to share one secret page with a small group (no user accounts needed).


  1. Edit the page in the Block Editor.
  2. In the Post/Page sidebar, open Summary → Visibility.
  3. Choose Password Protected, set a strong password, Update.
  4. Share the page URL + password with your audience.

Good for: quick shares, one-off docs, client preview pages.
Limitations: no user tracking, no “logged-in” requirement, no per-user access.


Option B: Make the page Private

Only logged-in users with the proper role (Editor/Admin; Authors for their own posts) can view it.

  1. Edit the page.
  2. Set Visibility → Private, click Update.

Good for: internal notes, admin-only pages.
Limitations: too restrictive for typical members/subscribers; not suitable for public+members mix.


Method 2 — Require login with a restriction plugin (no code)

If you want a “friendly” lock that asks visitors to log in (and redirects them back correctly), use a lightweight content restriction plugin. You get per-page controls, role targeting, and better UX than the basic “Private” setting.

Solid plugin choices

  • Members (by MemberPress): free, clean UI, role & capability editor + content restriction.
  • Restrict Content (free core): simple “require login” toggle on pages/posts.
  • WP-Members: adds login/registration on the front end and blocks content for non-users.

(Use one, not all.)

Example with Members (free)

  1. Install Members → Activate.
  2. Edit the page you want to protect.
  3. Scroll to the Content Permission panel (or “Restrict Content”).
  4. Enable Restricted and select Logged-in Users (or a specific role, e.g., Subscriber).
  5. Update the page.
  6. Go to Members → Settings to customize the redirect for visitors who aren’t logged in (e.g., send them to /login/ and then back).

Why this is nice

  • Proper “please log in” flow with redirect after login.
  • Can target specific roles or capabilities (e.g., “only Customers”).
  • No code; quick to roll out site-wide.

Watch for

  • Caching: make sure your caching plugin doesn’t serve a cached “logged-in” version to logged-out users. Exclude the protected page and the login page from cache.
  • Menus: hide links to private pages for logged-out users (some themes/plugins add “show only to logged-in users” on Menu items; otherwise use conditional menus or a small snippet—details at the end).

Method 3 — Add a small code snippet to force login (flexible & fast)

If you prefer code (or want a universal pattern), use a redirect that catches non-logged-in visitors and sends them to the login page. You can target specific page IDs, templates, or URL patterns.

Add to a functionality plugin (recommended) or your child theme’s functions.php. Don’t edit a parent theme directly.

A) Protect specific pages by ID

add_action('template_redirect', function () {
    if ( is_user_logged_in() ) return;

    // List page IDs that require login
    $protected_ids = [123, 456, 789];

    // If viewing any of those pages and not logged in → redirect to login
    if ( is_page($protected_ids) ) {
        auth_redirect(); // sends to /wp-login.php?redirect_to=current_url
        exit;
    }
});

B) Protect a page and all its children

Useful for “/resources/” + all subpages.

add_action('template_redirect', function () {
    if ( is_user_logged_in() ) return;

    $parent_slug = 'resources'; // parent page slug
    if ( is_page() ) {
        $page = get_queried_object();
        $ancestors = get_post_ancestors($page);
        $parent = $ancestors ? end($ancestors) : $page->ID;
        if ( $parent && $parent_slug === get_post_field('post_name', $parent) ) {
            auth_redirect();
            exit;
        }
    }
});

C) Protect by URL prefix (e.g., anything under /members/)

add_action('init', function () {
    if ( is_admin() || is_user_logged_in() ) return;

    $request_uri = $_SERVER['REQUEST_URI'] ?? '';
    if ( strpos($request_uri, '/members/') === 0 ) {
        auth_redirect();
        exit;
    }
});

Why this is nice

  • Zero plugin overhead.
  • Works with any theme.
  • Easy to scale from a single page to a whole section.

Watch for

  • Login page loop: don’t protect /wp-login.php. auth_redirect() handles this safely.
  • Custom login pages: replace auth_redirect() with wp_redirect( $custom_login_url ) and exit; if you use a front-end login page; remember to append a redirect_to param.
  • Caching/Edge Cache: exclude protected URLs from full-page cache.

Method 4 — Use a membership/LMS if you already run gated content

If you’re running courses, memberships, or paid downloads, it’s cleaner to use the access controls inside the platform you already have. These usually handle login prompts, redirects, checkout flows, and role assignment.

Good choices:

  • MemberPress (memberships, courses, coupons, rules by tag/category/page).
  • Paid Memberships Pro (flexible membership levels, rules, front-end login/register).
  • LearnDash / LifterLMS (if the gated content is course lessons).
  • Easy Digital Downloads (EDD) + Passes (if you gate downloads).

Pattern

  • Create a rule that targets the page (or category).
  • Assign that rule to Logged-in users or specific membership levels.
  • Set the redirect for non-members: login page or pricing.

Why this is nice

  • Unified UX with your checkout/membership levels.
  • You can sell access if needed (free or paid).

Watch for

  • Don’t stack multiple restriction plugins; pick one system to avoid conflicts.
  • Test the full flow as a logged-out user and as each role/level.

Important details most people miss

1) Caching and CDNs

  • Exclude login pages and protected URLs from page cache.
  • If using Cloudflare or a similar CDN with “cache everything” rules, carve out exceptions or use a bypass cookie for logged-in users.

2) Menus that reveal private URLs

  • In Appearance → Menus, some themes/plugins add a “Display for logged-in users only” checkbox. Use it.
  • If not, consider a conditional menus plugin or this tiny filter:
add_filter('wp_nav_menu_objects', function ($items) {
    $logged_in = is_user_logged_in();
    foreach ($items as $k => $item) {
        // Example: mark menu items with CSS class 'only-logged-in' or 'only-logged-out'
        if (in_array('only-logged-in', $item->classes, true) && !$logged_in) unset($items[$k]);
        if (in_array('only-logged-out', $item->classes, true) && $logged_in) unset($items[$k]);
    }
    return $items;
});

Add the class on a menu item (Screen Options → CSS Classes), and the filter will hide it based on login state.

3) Search and sitemaps

  • If a page is members-only, consider noindex to avoid teasing searchers with content they can’t access.
  • Most SEO plugins (Yoast/Rank Math) let you set noindex per page or per category.
  • For entire sections: noindex the category archive and its posts if they’re fully gated.

4) Friendly login experience

  • Use a front-end login page with your brand. Plugins like Theme My Login, WPForms User Registration, or your membership plugin can handle this.
  • After login, redirect back to the originally requested page (redirect_to parameter) so the flow feels seamless.

5) Auditing access

  • If multiple editors manage content, document the rule: which pages are gated, who can change the restriction, what the expected redirect is.
  • Re-test after major updates or plugin changes.

Which method should you pick?

  • One page, quick lock, no accounts needed: Password Protect (Method 1A).
  • Internal-only content (admins/editors): Private visibility (Method 1B).
  • Logged-in gate for a few pages without coding: Content restriction plugin (Method 2).
  • Precision control (IDs, sections, URL prefixes) in a lean setup: Code snippet (Method 3).
  • You already sell access / have members: Use your membership/LMS rules (Method 4).

Copy-paste snippets for faster setup

Redirect non-logged-in users from a single page

add_action('template_redirect', function () {
    if ( ! is_user_logged_in() && is_page(123) ) {
        auth_redirect();
        exit;
    }
});

Redirect non-logged-in users from a URL prefix

add_action('init', function () {
    if ( is_admin() || is_user_logged_in() ) return;
    if ( isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '/members/') === 0 ) {
        auth_redirect();
        exit;
    }
});

Hide menu items by login state via CSS classes

add_filter('wp_nav_menu_objects', function ($items) {
    $logged_in = is_user_logged_in();
    foreach ($items as $k => $item) {
        if (in_array('only-logged-in', $item->classes, true) && !$logged_in) unset($items[$k]);
        if (in_array('only-logged-out', $item->classes, true) && $logged_in) unset($items[$k]);
    }
    return $items;
});


Smart Ideas, Straight to You

Subscribe for free updates — posts, tools, and strategies to help you create smarter and grow faster.

Todays Funda
Todays Funda

TodaysFunda is the home base for digital creators, designers, and entrepreneurs. From WordPress optimization to social media growth, we publish practical guides, resources, and strategies to help you create smarter, grow faster, and stay inspired on your journey.

Leave a Reply

Your email address will not be published. Required fields are marked *