Disable Direct Access to a WordPress Page

Quick Summary
- Hook a function to template_redirect that checks wp_get_referer() and redirects visitors who open the protected page directly or from any other page.
- Replace ADD_YOUR_PAGE_ID with the protected page's ID and enter the allowed URL exactly, including https:// and the trailing slash.
- Use a different page ID for the redirect target to avoid a loop, and don't rely on the browser-sent referrer for real access control.
Sometimes a WordPress page should only be reached from one specific page, such as a thank-you page after a form or a download page after a sign-up. This snippet checks where the visitor came from and redirects them if they opened the page directly or from anywhere else. Add it to your child theme’s functions.php or a custom plugin.
<?php
add_action('template_redirect', function () {
//Page you want to redirect
if (!is_page(ADD_YOUR_PAGE_ID)) {
return;
}
if (wp_get_referer() == 'ENTER_THE_URL_FROM_WHERE_IT_SHOULD_BE_ACCESSIBLE') {
return;
}
//Where You Want To Redirect
wp_redirect(get_permalink(ADD_YOUR_PAGE_ID));
exit;
});
?>How it works
template_redirectruns just before WordPress loads the page template, which is early enough to redirect.is_page( ADD_YOUR_PAGE_ID )makes the function return early on every other page. Replace the placeholder with the ID of the page you want to protect.wp_get_referer()returns the URL the visitor came from. If it matches the URL you enter exactly, the page loads normally, so include the full address withhttps://and the trailing slash.- Otherwise
wp_redirect()sends the visitor to the permalink of the page ID in the last lines, andexitstops WordPress from loading anything else.
Before you use it
- The redirect target needs a different page ID than the protected page. If you use the same ID in both places, the page redirects to itself in an endless loop.
wp_get_referer()only returns URLs from your own site. A referrer from another domain comes back asfalse, so the allowed page has to be on the same site.- The referrer is sent by the browser. It can be missing or faked, so treat this as a convenience, not as real access control for private content.
- If your
functions.phpalready starts with<?php, leave out the opening and closing PHP tags when you paste the code.
Related articles
- redirecting to the homepage when a form value is missing: a JavaScript way to keep visitors off a page
- the same template_redirect hook in a WooCommerce logout fix: another early redirect before the template loads

