Test a Shopify geolocation redirect without a VPN
By Beacon Wave Studio · · 8 min read
The way most merchants test a country redirect is to ask a friend. “Can you open the site from Canada and tell me what happens?” The friend reports back an hour later, the merchant changes a rule, and asks again. People with a VPN do slightly better, until they discover the VPN’s Canadian exit node is detected as the United States, or that their browser remembered the answer from the previous attempt and now shows nothing at all.
This is a guide to testing geolocation rules properly, from one desk, in about fifteen minutes. It uses GeoBeacon, which was built with a test mode for exactly this, but the list of cases at the end applies to any geolocation app on Shopify and is worth running against whichever one you have.
Why a VPN is the wrong tool
A VPN changes your IP address. It does not change the two other things that decide what a geolocation script does: what your browser has stored from previous visits, and which page you are on. So a VPN test conflates three variables and lets you change only one of them, slowly, with a subscription. It also tests the wrong detector: Shopify works out a visitor’s country from the request, and if the exit node your VPN chose is registered to a different country than it advertises, you are testing the VPN provider’s address book rather than your rules.
What you want instead is a switch that says “pretend this browser is in Germany for this one page view, and remember nothing”. That is what GeoBeacon’s query parameter does.
The query parameter
Append ?geobeacon=DE to any storefront URL and the script treats the visitor as being in Germany. Any two-letter country code works: ?geobeacon=CA, ?geobeacon=JP. The rules run exactly as they would for a real German visitor, so you see the real popup with the real text, or the real redirect to the real destination. Two things are different from a normal visit. Nothing is written to storage, so you can reload with a different code and get a fresh decision each time. And the parameter is stripped from the URL before any redirect, so a URL destination with “keep the page path” turned on receives the clean path and not your test flag.
The opposite switch is ?geobeacon=off, which makes the script stay quiet for one page view. It is useful when you want to look at a page as a real visitor would see it without the popup in the way, and for support: if a shopper says they are stuck, sending them a link with the parameter is a faster fix than explaining how to clear site data.
Test mode is a client-side switch and nothing about it reaches our servers; GeoBeacon has no per-visitor tracking to turn off, which is part of why it does not charge per visitor. It is also why the parameter must not appear in links you publish. It is not secret, it just makes every click on that link behave like a visit from the country in the URL.
Reading the console
Most “the popup does not show” reports are not bugs. They are the script deciding, correctly, not to act. GeoBeacon exposes that decision: open the GeoBeacon app embed in the theme editor, tick “Log decisions to the browser console”, save, and every page view prints one line to the browser console. Either skipped: with a reason, or decision with the action it took.
| Reason | What happened | What to do |
|---|---|---|
| disabled | GeoBeacon is switched off under Behaviour. | Turn it on. The embed can be enabled in the theme while the app is off. |
| design-mode | You are looking at the theme editor or a theme preview. | Expected. Use the “Preview popup in the theme editor” setting to style it there. |
| remembered | This browser answered the popup, or was redirected, within the remember period. | Clear the geobeacon:choice key in localStorage or use a private window. |
| excluded-path | The page is cart, checkout, account, a password page, an app proxy path, or one of your own exclusions. | Expected. Switching market mid-checkout would break the order. |
| came-from-own-store | The visitor arrived from a domain listed in your known hosts. | Expected. It stops two of your stores bouncing a visitor between them. |
| bot | The user agent looks like a crawler and bot skipping is on. | Expected, and good for SEO. |
| no-rules | No enabled rule exists. | Enable at least one rule. |
When detection does run, a decision can still be “none”, and the console says why: no-matching-rule when the detected country is in no rule and there is no catch-all, country-not-offered when the rule points at a market your store does not sell to, and already-there when the visitor is already browsing the market and language the rule would send them to. The second of those catches a common configuration mistake: a rule for Switzerland that sends visitors to a Swiss market that was never added under Shopify Markets does nothing, silently, unless something tells you.
A fifteen-minute test plan
Run this in a private window with console logging on. Each line is one URL and one expected outcome.
- Each rule, once. For every rule, open the homepage with
?geobeacon=and one of its countries. You should see the popup naming the right destination, or the redirect if you are in redirect mode. Check the country name and the target label in the popup text; a{country}placeholder left in by mistake shows up here. - A country in no rule. Pick one you do not sell to. Expect
no-matching-ruleand no popup, unless you have a catch-all rule, in which case expect that. - The already-there case. Open the German market URL, usually
/de-de/or your German domain, with?geobeacon=DE. Expectalready-there. If a popup appears, the rule is sending German visitors somewhere other than the German market, which is the setup that produces redirect loops. - Language without market. If a rule switches language only, test it from a market that offers that language and one that does not. In the second case expect the language to be dropped and either
already-thereor a market-only switch. - A deep page with keep-path. For URL destinations with path preservation, open a product page with the parameter and confirm the destination URL ends in the same product path, with no
geobeacon=left in the query string. - The excluded paths. Open
/cartwith the parameter. Expectexcluded-path. Do the same for any campaign landing page you added to your own exclusions. - Stay here, then reload. Without the parameter, trigger the popup for real if you can, or briefly set a rule for your own country, click Stay here, and reload. Expect
rememberedfor the number of days you configured. Then clear the key and confirm it comes back. - Phone. Repeat the first step on a phone. The popup position you chose looks different on a small screen, and a bottom-anchored popup can sit under a theme’s sticky add-to-cart bar.
Things that are not the app’s fault
A few outcomes look like bugs during testing and are not. If a market redirect lands on the right market but the wrong currency, the market’s currency is set under Shopify Markets, not in the app; GeoBeacon submits Shopify’s own localization form, the same one the theme’s country selector uses, so what you get is what the theme would give. If a language switch shows an untranslated page, the translations are missing in Shopify, and the switch worked. And if Shopify’s own automatic redirection is also on, test with it off first; two systems deciding where a visitor should go is one too many, and our troubleshooting checklist covers how to pick one.
When you are done, turn console logging off. It is harmless, but a storefront that narrates its decisions to anyone who opens developer tools is untidy, and you will want a clean console the next time something unrelated breaks.
Frequently asked questions
How can I test a Shopify country redirect without a VPN?
With GeoBeacon, add ?geobeacon=XX to any storefront URL, where XX is a two-letter country code, and the script treats you as a visitor from that country for that page view without remembering anything. Other apps may offer a similar preview parameter; if not, a VPN or a colleague abroad is the only way to see the real behaviour.
Why does my geolocation popup not show when I test it?
The usual reasons are a remembered choice from an earlier test, a path the script excludes such as cart or checkout, the theme editor's preview mode, or a rule whose destination market is not offered in your Shopify Markets settings. Turning on GeoBeacon's console logging prints the exact reason it stayed quiet.
Does testing with the query parameter affect real shoppers?
No. The parameter only changes the country for the browser that has it in the URL, is stripped before any redirect, and stores nothing, so the next page view behaves normally. Real shoppers never see it unless you publish a link containing it, which you should not.
How do I reset the popup after I clicked Stay here during a test?
GeoBeacon remembers the choice in localStorage under the geobeacon:choice key for the number of days you configured. Remove that key in your browser's developer tools, or open a private window, and the popup is eligible to appear again. There is no server-side state to clear because none is kept.