{"id":316319,"date":"2026-05-22T11:35:17","date_gmt":"2026-05-22T11:35:17","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/hwp-frontend-gatekeeper\/"},"modified":"2026-05-22T11:36:52","modified_gmt":"2026-05-22T11:36:52","slug":"frontend-gatekeeper","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/frontend-gatekeeper\/","author":179,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.0","requires":"5.7","requires_php":"8.0","requires_plugins":null,"header_name":"Frontend Gatekeeper","header_author":"Jordan Hlebarov","header_description":"Hides the public frontend unless a configured URL parameter is present, then keeps that parameter on same-site links.","assets_banners_color":"485c78","last_updated":"2026-05-22 11:36:52","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/hwp.bg\/frontend-gatekeeper\/","header_author_uri":"https:\/\/hwp.bg","rating":0,"author_block_rating":0,"active_installs":0,"downloads":17,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"jdbg","date":"2026-05-22 11:36:52"}},"upgrade_notice":{"1.0.0":"<p>Initial release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3543665,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3543665,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3543665,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3543665,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[1912,802,1281,2475,31388],"plugin_category":[],"plugin_contributors":[263983],"plugin_business_model":[],"class_list":["post-316319","plugin","type-plugin","status-publish","hentry","plugin_tags-access-control","plugin_tags-coming-soon","plugin_tags-maintenance-mode","plugin_tags-preview","plugin_tags-private-site","plugin_contributors-jdbg","plugin_committers-jdbg"],"banners":{"banner":"https:\/\/ps.w.org\/frontend-gatekeeper\/assets\/banner-772x250.png?rev=3543665","banner_2x":"https:\/\/ps.w.org\/frontend-gatekeeper\/assets\/banner-1544x500.png?rev=3543665","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/frontend-gatekeeper\/assets\/icon-128x128.png?rev=3543665","icon_2x":"https:\/\/ps.w.org\/frontend-gatekeeper\/assets\/icon-256x256.png?rev=3543665","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Frontend Gatekeeper hides the public frontend of your WordPress site unless visitors arrive with a configured URL parameter and value. It is useful for staging sites, soft launches, client previews, and pre-release content where you want to share a single shareable link instead of issuing individual user accounts.<\/p>\n\n<p>Logged-in users always see the site normally, so editors and administrators are never blocked.<\/p>\n\n<h4>Features<\/h4>\n\n<ul>\n<li>Hide the entire public frontend with a single toggle.<\/li>\n<li>Configurable parameter name and secret value, set per site.<\/li>\n<li>Custom blocked message shown to unauthorized visitors (served with a 404 status).<\/li>\n<li>Same-site link propagation: WordPress-generated links, menus, and block content automatically carry the access parameter forward, so visitors stay authorized while browsing.<\/li>\n<li>Footer-script fallback that adds the parameter to links and forms rendered outside normal WordPress filters.<\/li>\n<li>Gutenberg and block-theme aware through the <code>render_block<\/code> filter and <code>WP_HTML_Tag_Processor<\/code> when available.<\/li>\n<li>Multisite-aware URL scoping for subdomain and subdirectory networks: access on <code>\/site-a\/<\/code> will not leak the token to <code>\/site-b\/<\/code>.<\/li>\n<li>Logged-in users, wp-admin, REST API, AJAX, cron, and <code>wp-login.php<\/code> are always allowed through.<\/li>\n<\/ul>\n\n<h4>Typical use cases<\/h4>\n\n<ul>\n<li>Sharing a staging or pre-launch site with clients and stakeholders.<\/li>\n<li>Gating a soft launch behind a single link instead of provisioning accounts.<\/li>\n<li>Hiding draft or campaign content until you are ready to publish.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>frontend-gatekeeper<\/code> folder to the <code>\/wp-content\/plugins\/<\/code> directory, or install the plugin through the WordPress Plugins screen.<\/li>\n<li>Activate the plugin through the <strong>Plugins<\/strong> screen in WordPress. On multisite, you can network-activate or activate per site.<\/li>\n<li>Go to <strong>Settings &gt; Frontend Gatekeeper<\/strong> and configure the parameter name, parameter value, and blocked message.<\/li>\n<li>Enable the gate and share the generated access URL.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"what%20happens%20to%20logged-in%20users%3F\"><h3>What happens to logged-in users?<\/h3><\/dt>\n<dd><p>Logged-in users are never gated. Administrators, editors, and any other authenticated visitor see the site as normal.<\/p><\/dd>\n<dt id=\"what%20do%20unauthorized%20visitors%20see%3F\"><h3>What do unauthorized visitors see?<\/h3><\/dt>\n<dd><p>They see your configured blocked message, served with an HTTP 404 status and no-cache headers, so the site does not advertise that it exists at that URL.<\/p><\/dd>\n<dt id=\"will%20the%20access%20parameter%20spread%20to%20external%20links%3F\"><h3>Will the access parameter spread to external links?<\/h3><\/dt>\n<dd><p>No. The parameter is only appended to same-site URLs. Links to other domains, mail\/tel\/sms\/javascript URIs, and fragment-only links are left alone.<\/p><\/dd>\n<dt id=\"does%20it%20work%20on%20multisite%3F\"><h3>Does it work on multisite?<\/h3><\/dt>\n<dd><p>Yes. Settings are stored per site, and on subdirectory networks the parameter is only appended to links that fall under the current site's path.<\/p><\/dd>\n<dt id=\"is%20this%20a%20real%20security%20boundary%3F\"><h3>Is this a real security boundary?<\/h3><\/dt>\n<dd><p>No. The access parameter is a soft gate suitable for previews and staging. Anyone with the link gets in, and the value can appear in browser history and server logs. Use real authentication for anything sensitive.<\/p><\/dd>\n<dt id=\"does%20it%20block%20the%20rest%20api%2C%20admin%2C%20or%20login%20page%3F\"><h3>Does it block the REST API, admin, or login page?<\/h3><\/dt>\n<dd><p>No. wp-admin, AJAX, cron, the REST API, and <code>wp-login.php<\/code> are always allowed through so the site stays manageable.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<li>Frontend gate that hides public WordPress pages unless a configured URL parameter and value are present.<\/li>\n<li>Per-site WP Admin settings under <strong>Settings &gt; Frontend Gatekeeper<\/strong> with an On\/Off toggle switch.<\/li>\n<li>Generated access URL display in the settings screen, with a Copy-to-clipboard button and full-URL preview.<\/li>\n<li>Logged-in users always bypass the gate, alongside wp-admin, REST, AJAX, cron, and <code>wp-login.php<\/code>.<\/li>\n<li>Same-site URL propagation for WordPress-generated links.<\/li>\n<li>Classic menu link attribute support.<\/li>\n<li>Gutenberg and block-based theme support through the <code>render_block<\/code> filter.<\/li>\n<li>Footer-script fallback for frontend links\/forms generated outside normal WordPress rendering.<\/li>\n<li>Multisite-aware URL scoping for subdomain and subdirectory networks.<\/li>\n<\/ul>","raw_excerpt":"Hide the public WordPress frontend behind a secret URL parameter. Anyone with the link gets in; everyone else sees a 404.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/316319","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=316319"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/jdbg"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=316319"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=316319"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=316319"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=316319"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=316319"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=316319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}