WordPress redirect redirecting too many times or not at all

Short Answer

I am trying to simply redirect users to a login page if they go to the
account page without being logged in.

Try with is_page() once again, but use the correct syntax: (see home_url() for more information about the function, but it’s an easy way to get your WordPress URL and you can pass any valid path like /login/)

add_action( 'template_redirect', 'redirect_if_user_not_logged_in' );

function redirect_if_user_not_logged_in() {
    if ( !is_user_logged_in() && is_page( 'account' ) ) {
        wp_redirect( home_url( '/login/' ) );
        exit;
    }
}

More Details

I first tried adding this code to the functions.php

Well, if your function actually starts like so (note the && is_page part), then that’s a (PHP) syntax error..

function redirect_if_user_not_logged_in() && is_page('example.com/account') {

Secondly, you’ve incorrectly used is_page(): is_page('example.com/account') — if you want to check if the main WordPress query (which runs automatically on page load) is for a Page (post type page) with a specific slug (that’s used in the permalink) like account, then the correct syntax is:

is_page( 'account' )
// pass just the Page slug; don't include the "example.com/"

which returns true if the current page URL is like https://example.com/account/ and that your WordPress URL is https://example.com/ (with or without the slash).

Again, I tried this with several different hooks as well as ‘init’ and
‘admin_init’.

admin_init runs only on the admin side, i.e. wp-admin, so you would not want to use that hook for what you’re trying to do.

init would work if you just wanted to redirect without checking whether you are on a specific Page.

Otherwise, you should use a later hook which runs after WordPress finished parsing the current URL and setup the main query.

So for example, you could (and most devs, including myself, would also) use the template_redirect hook, like you originally tried with.

This resulted in the “ERR_TOO_MANY_REDIRECTS” error on both Chrome and
Microsoft Edge. I would’ve thought that this would just redirect once
but it appears that it gets caught in a loop.

Yes, because the hook runs on every page load/request, and because you only checked if the current user is logged-in, then as long as the user is not (yet) logged-in, then the redirect will happen on each page request. It can be illustrated like so:

  1. I visited your account page at example.com/account
  2. The template_redirect hook ran and your code checked if I was logged-in to your site
  3. If was not and thus your code redirected me to example.com/login
  4. On the login page, the template_redirect hook ran and your code checked if I was logged-in to your site
  5. If was not and thus your code redirected me to example.com/login
  6. On the login page, the template_redirect hook ran and your code checked if I was logged-in to your site
  7. … and it went on and on like that without an ending..

Eventually, the browser gave up and thrown the error, “ERR_TOO_MANY_REDIRECTS”.

Because your code infinitely redirected me (or the current user) to example.com/login..

And actually, you’ve also incorrectly used wp_redirect(): wp_redirect( 'example.com/login' ) — because that would actually redirect you to https://example.com/example.com/login and not https://example.com/login (assuming your WordPress URL uses htpps, i.e. the secure protocol).

So make sure you use a fully-qualified URL like https://example.com/login and not just example.com/login, or a relative path if you wanted to redirect to a page on your own site, but ensure the path is valid (i.e. it exists). 🙂