Two cities, two answers, one search
Search "best coffee shop" from downtown Vancouver: three map listings. Drive to Surrey, type the exact same words: the pack reshuffles. Different names, different order, sometimes a different count.
That reshuffle is the whole job in local SEO. The pack, the map plus the businesses stacked under it, is assembled around where the searcher is standing. Three slots, sometimes two, sometimes an ad wedged on top of the organic ones. You're never holding one fixed thing up against another. Both sides move. Here's how I read two cities without burning an afternoon on Highway 99.
Why your desk lies to you
Search a local term from your office in Vancouver and the answer is glued to your IP, your device location, and your account history. It says next to nothing about Calgary.
Bolt "in Calgary" onto the query and you get a hint, a weak one, still filtered through your own location and history. A client asks whether they show up in Kelowna, and squinting at your Vancouver results won't tell you. You have to make Google believe you're standing in that city. Three URL parameters do exactly that.
The three parameters that move you
glis the country.gl=cafor Canada,gl=usfor the States.hlis the interface language.hl=enfor English,hl=frfor French.uuleis the encoded location. It carries the exact place ("Surrey,British Columbia,Canada") in a string Google reads as "the searcher is physically here."
A geo-targeted URL looks like this:
https://www.google.com/search?q=coffee+shop&gl=ca&hl=en&uule=w+CAIQICIeU3VycmV5LEJyaXRpc2ggQ29sdW1iaWEsQ2FuYWRh
gl and hl set the frame. The uule picks the city. For pack work, uule is the parameter that decides who shows up.
Building a uule
It isn't magic. It's an encoding of a plain location name, and you can build one by hand. Two flavours exist: one for GPS coordinates, one for a canonical location name. You want the second. The name has to match Google's list character for character, comma-separated, no stray spaces: Surrey,British Columbia,Canada.
The pattern:
w+CAIQICI + <length key> + <base64 of the canonical name>
Three pieces:
- The prefix
w+CAIQICIis constant for canonical-name uules. - The length key is a single character encoding the length of your string. Index into this 64-character alphabet by the character count:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_. "Surrey,British Columbia,Canada" is 30 characters, and slot 30 ise. - The base64 of the name, UTF-8 encoded. "Surrey,British Columbia,Canada" encodes to
U3VycmV5LEJyaXRpc2ggQ29sdW1iaWEsQ2FuYWRh.
Stitched together: w+CAIQICIeU3VycmV5LEJyaXRpc2ggQ29sdW1iaWEsQ2FuYWRh.
Do the same for Vancouver. 33 characters (key h), base64 VmFuY291dmVyLEJyaXRpc2ggQ29sdW1iaWEsQ2FuYWRh, giving:
w+CAIQICIhVmFuY291dmVyLEJyaXRpc2ggQ29sdW1iaWEsQ2FuYWRh
A short Python function prints these for any location. The length is the UTF-8 byte count, not the character count, so accented city names still work, and a single byte covers every entry in Google's dataset:
import base64
def uule(name):
b = name.encode("utf-8")
# role=2, producer=32, then the canonical name as a length-delimited field
proto = bytes([0x08, 0x02, 0x10, 0x20, 0x22, len(b)]) + b
return "w+" + base64.b64encode(proto).decode()
print(uule("Surrey,British Columbia,Canada"))
# w+CAIQICIeU3VycmV5LEJyaXRpc2ggQ29sdW1iaWEsQ2FuYWRh
One rule breaks everything else: the name must be a real row in Google's Geotargets dataset. That's Google Ads' published list of every targetable place, with the exact spelling for each. Wrong province, a typo, a place that isn't listed, and the uule points at nothing. Copy the canonical name straight from that CSV before you encode.
Comparing two cities, step by step
The job: Vancouver against Surrey, "emergency plumber".
- Pull both canonical names from the Geotargets dataset:
Vancouver,British Columbia,CanadaandSurrey,British Columbia,Canada. - Encode each into its uule.
- Build two URLs that differ only in the uule. Keep
q=emergency+plumber,gl=ca,hl=enidentical on both. - Run both. Write down the top three: business name, rank, and whether an ad crashed the pack.
- Diff the two lists.
Hold everything constant except location. Change only the uule, watch the pack change, and geography is the only variable left standing. Move two things at once and you've learned nothing about which one mattered.
What to read in the diff
Rank position is the obvious number. It's also the least useful. What I check every time:
Who's even in the pack. A business that owns Vancouver can be a ghost in Surrey. That's proximity. If your client has one location downtown, ranking in Surrey is often a fantasy, and that's a conversation to have on day one, not month three.
Pack size. Three slots in one city, two in the next. Fewer slots, higher bar.
Ads. A local service ad above the organic listings eats the best real estate. If Surrey's pack carries one and Vancouver's doesn't, your Surrey listing effectively sits a rung lower at the same rank.
Category drift. "Plumber" leans emergency in one city and general contractor in the next, depending on who bothered to optimize. The pack mirrors local supply, not just your profile.
A British Columbia reality check
Metro Vancouver is a stack of separate search markets jammed shoulder to shoulder: Vancouver, Burnaby, Surrey, Richmond, Coquitlam. A fifteen-minute drive crosses several pack boundaries. A Burnaby shop can own Burnaby and vanish one municipality over.
Which is why "we rank number one" is a claim I always answer with a question: where. Number one from your own doorstep is common and close to worthless. Number one from across town is the one that pays rent. Comparing the pack across two BC cities turns a vague brag into a map of where you actually win.
The uule is what lets you draw that map from a desk. Set the query once, swap the location, read both packs side by side. Fastest way I know to answer "do we show up over there" without leaving the province. And if you'd rather not hand-encode anything, the compare tool on this site builds both URLs for you — one query, two cities, correct uule on each.