Version 1.5.0
PBJ Geo Viewer makes your WordPress site view-only for visitors outside the countries you allow. Selected countries get the full interactive experience. Everyone else can still browse every page on the site, but cannot:
Search engines and admins are always exempt, so SEO and your own access are unaffected.
CF-IPCountry header). If you're not on Cloudflare, the plugin falls back to a free IP-to-country API with 24-hour per-IP caching.pbj-geo-viewer.zip (or pbj-geo-viewer-1.5.0.zip).To upgrade later: just upload the newer zip the same way. WordPress will prompt to replace the existing copy. Your settings are preserved across upgrades — the plugin handles schema migrations automatically.
Since 1.5.0 the Settings tab is a guided five-step walkthrough — each step in its own numbered card with a plain-English "what this does" explanation. It's one form: work through the steps, then click Save settings once at the bottom (everything saves together).
In the Countries grid, tick every country the rule should apply to. Type into the Filter countries… box to narrow the list; Select all shown and Clear all act on the filtered view, and a live count shows how many are selected. The full ISO 3166-1 country set is available.
Step 1 also holds two related settings:
198.51.100.*), one per line; matching visitors are always view-only regardless of country. Search engines and logged-in admins/editors stay exempt.Four independent toggles:
/cart and /checkout back to the shop with a notice query parameter. Rejects Add to Cart server-side as a fallback.<input type="submit"> buttons are visually disabled. Server-side POST interception returns HTTP 451 for blocked form actions.Two independent notice toggles:
Both default to ON. The banner text and inline message are fully editable.
In the Admin IP allowlist, enter one IP or CIDR per line, e.g.:
203.0.113.5
198.51.100.0/24
2001:db8::1
Any visitor from a listed IP is treated as fully allowed regardless of country. Add your home and office IP here before going live — otherwise, the next time you visit from a blocked country (or VPN through one), you'll lose the ability to interact with your own site. (Logged-in editors and admins are also always exempt, so as long as you're logged in you're fine.)
The same card holds the Login username allowlist — usernames or emails that may sign in from blocked regions (a login-only exemption; admins and editors can always sign in) — and Geo cache (minutes), which controls how long an IP-to-country lookup is remembered.
The Diagnostics table in the last step shows:
If the country is wrong or showing as (unknown), check whether your site is actually proxied through Cloudflare and whether your hosting provider is forwarding the real client IP via X-Real-IP, X-Forwarded-For, or CF-Connecting-IP.
Once configured, the plugin runs automatically. There's nothing to push or sync — every page request is evaluated in real time.
To preview how blocked visitors see your site:
The banner and inline notices should appear, cart and forms should be disabled, and /cart should redirect.
Add or remove countries any time. Changes take effect immediately for new requests. Cached country lookups for individual visitor IPs persist for 24 hours by default — that's fine in practice because countries-per-IP almost never change.
If you need to flush the geo cache immediately (e.g., a customer complains they're misclassified), deactivate and reactivate the plugin. The deactivation handler clears all pbj_geo_* transients.
The plugin maintains a list of known crawler user-agents (Googlebot, Bingbot, DuckDuckBot, Slurp, GPTBot, ClaudeBot, PerplexityBot, Applebot, FacebookExternalHit, TwitterBot, LinkedInBot, ScreamingFrog SEO Spider, and many others). Anything matching one of those strings is always treated as fully allowed.
This means:
If you want to add a private crawler or scraper to the always-allowed list (e.g., your own monitoring bot), use the admin IP allowlist instead — that's the more reliable mechanism for identifying your own infrastructure.
Upload the newer zip via Plugins → Add New → Upload Plugin. WordPress will prompt to overwrite. Settings are preserved.
The plugin's Update URI header points at https://pbj.tech/plugins/pbj-geo-viewer. To enable auto-updates from your own server, host a JSON manifest at that URL:
{
"version": "1.0.2",
"package": "https://pbj.tech/dl/pbj-geo-viewer-1.0.2.zip",
"tested": "6.5",
"requires": "5.8",
"requires_php": "7.4",
"url": "https://pbj.tech/plugins/pbj-geo-viewer"
}
WordPress checks for updates roughly twice a day. When the remote version is newer than the installed version, Plugins → Installed Plugins shows the usual update prompt.
If the update server is unreachable, the updater silently falls back to "no update available" — your site is never harmed by a broken update endpoint.
CF-IPCountry header isn't present and the ip-api.com fallback isn't reaching the server. Confirm your site is proxied through Cloudflare with "DNS only" turned OFF, or that your server allows outbound HTTP to ip-api.com./cart and /checkout aren't redirecting. Confirm the WooCommerce cart, checkout, and Add to Cart toggle is enabled. Confirm WooCommerce itself is active. The redirect runs at template_redirect priority 1 — if another plugin is hijacking the same hook, raise the priority or temporarily disable the conflicting plugin to confirm.~/Documents/Claude/Projects/Wordpress Plugins/, mirrored to the WordPress Plugins/pbj-geo-viewer/ folder in Google Drive.pbj_geo_viewer_settings). A separate pbj_geo_viewer_db_version option tracks the schema version for upgrade migrations.pbj_geo_. Cleared on plugin deactivation and on uninstall.