Customization PHP Intermediate

Redirect Non-Logged-In Users to the Login Page

Last updated: May 6, 2026

Most WordPress sites are fully public by default, any visitor can browse any page without authentication. For membership sites, client preview environments, internal tools, company intranets, and staging sites you don’t want indexed or accessed publicly, restricting front-end access to logged-in users is a fundamental requirement. This snippet forces unauthenticated visitors to the login page while allowing a small set of public pages and WooCommerce commerce pages to remain accessible.

The Code

Add this to your functions.php or a site-specific plugin. It hooks into template_redirect, which fires after WordPress has determined what page is being requested but before any template is rendered. If the visitor is not logged in and no exception applies, they’re sent to the login page with a redirect_to parameter that brings them back to their intended destination after successful authentication.

The Exception Logic

The snippet allows three categories of requests through without authentication. First, logged-in users, the most important check, and the one that prevents infinite redirect loops. Second, 404 pages, unauthenticated visitors who land on a broken URL see the 404 page rather than being bounced to login, which is cleaner and more informative. Third, WooCommerce commerce pages, shop, cart, and checkout, are kept accessible so that guest checkout functionality continues to work if your store allows it.

The $public_slugs array allows specific pages by their URL slug. Privacy policy and terms of service pages are included by default because they may be required to be publicly accessible under GDPR and similar regulations. Add any other public-facing pages your site requires, a public landing page, an unsubscribe confirmation page, or a public documentation index.

The Redirect Destination

wp_login_url() returns the WordPress login URL and accepts an optional redirect_to argument, the URL to send the user after successful login. Passing the current REQUEST_URI means a user who tries to visit /members/dashboard/ gets redirected to login, and after logging in is sent directly to /members/dashboard/ rather than the WordPress admin or homepage. This significantly improves the user experience on sites where specific members have bookmarked internal pages.

Staging Environment Use

For staging environments, this snippet works well as a lightweight access gate, but note that search engine bots will also be redirected to the login page. Make sure your staging environment is either excluded from robots indexing through your server configuration or that the redirect itself prevents crawling. A 302 temporary redirect to the login page should prevent Googlebot from indexing staging content, but combining it with a robots.txt disallow or basic HTTP authentication at the server level is more reliable.

Performance

This snippet runs on every page request for unauthenticated users. The is_user_logged_in() check is lightweight, it’s a simple user session check, but the additional conditional checks add a small amount of overhead per request. On high-traffic public sites where only a portion of users need to be authenticated, consider server-level access control (HTTP Basic Auth) as a more efficient alternative.

functions.php
add_action( 'template_redirect', function() {
    // Allow these pages through without authentication
    if (
        is_user_logged_in()     ||
        is_404()                ||
        ( function_exists( 'is_woocommerce' ) && ( is_woocommerce() || is_cart() || is_checkout() ) )
    ) {
        return;
    }

    // Allow specific public pages by slug
    $public_slugs = [ 'privacy-policy', 'terms-of-service' ];
    if ( is_page( $public_slugs ) ) return;

    // Redirect to login with a redirect_to parameter so users land back
    // on the page they were trying to reach after logging in
    $redirect_to = urlencode( $_SERVER['REQUEST_URI'] ?? '/' );
    wp_redirect( wp_login_url( home_url( $_SERVER['REQUEST_URI'] ?? '/' ) ), 302 );
    exit;
} );

Built by Nahnu Plugins

Need something more powerful than a snippet?

Our commercial plugins go further, built for serious WordPress sites with full support, updates, and documentation included.

Browse All Plugins →

This website uses cookies to enhance your browsing experience and ensure the site functions properly. By continuing to use this site, you acknowledge and accept our use of cookies.

Accept All Accept Required Only