This article is a two-parter. I cover:

  1. The challenges scaling strategies need to overcome
  2. The ideal solution for someone serious about
  3. The easy way I built for anyone to use in some scenarios

Why does this matter?

Suppose you’re a chain with 1000 locations, how should you go about managing paid search campaigns for each?

How about if you’re a long distance moving company, wanting to create a local campaign for every search like “long distance mover Phoenix” or “long distance mover Tuscon”?

Or what if you have 750 clients in the same niche?

Clearly, there are account management problems that need to be addressed.

Primary Challenge: Where Are Searchers?

Let’s start with a hypothesis: users are more likely to convert if the page they land on tailored to them. This is not a groundbreaking hypothesis.

Let’s go a little deeper: if a user is expecting a local landing page, they will be more likely to convert on a local page.

If a user searches in a city like Phoenix the user expects an experience tailored to Phoenix.

The kicker is, searches won’t always show the location the user is referring to.

“Near me,” “local” or searches that leave out the location make it hard to tailor the ad experience.

A well thought out search strategy addresses this challenge.

Addressing The Primary Challenge: Two Common Strategies

There are two ways to address this problem:

  1. Use the {loc_physical_ms} parameter from value track parameters. (Fun fact: this is what powers my tool Easy Landing’s city insertion feature)
  2. Create a new campaign for every single geo. This, while not ideal, may be the only option for certain advertisers

The secondary challenge: out of area searchers

Let’s say you have a searcher in phoenix searching for a “New York City” location, how should you handle this?

The loc_physical_ms which shows the user’s physical location is useless here.

Addressing the secondary challenge: A hybrid strategy

There are two strategies to put in place to address the two styles of searches (implicit vs explicit).

The first strategy relies on signals from Google, the second is a more “hard coded” strategy.

I cover how to do both.

The “simpler” technical solution to location specific ads

Here’s the step-by-step process for the implicit style searches.

If someone searches “local oil change,” here’s the process for serving the best ad:

  1. Capture the loc_physical_ms
  2. Parse the value (most likely a zipcode). From here, return the city/county/state name or the details of your business closest to that location
  3. Render the localized page

Before you tell me “my cms doesn’t allow for this” there’s always a solution. If you need a creative solution email me at .

For explicit searches, like “tire store phoenix,” the solution is quite a bit easier.

  1. Generate a campaign for every single possible keyword (I made a free tool that helps with that here
  2. Ensure your ad copy has the city the user searched
  3. Set up your CMS to handle each new route (like /oil-change/phoenix)
  4. Serve the local page

The advantage of the explicit approach is you guarantee Google to see the tailored page. Google won’t see that you’ve tailored searches per location in the implicit example.

I show you a free way to insert the city into your landing page below.

Potential problems with the above and how to overcome them

Problem: Wrong location

As much as I would like to believe, Google is not all knowing. Sometimes, the location Google thinks someone is in is wrong.

Wrong location solution: track times where users show you’re wrong

Always give your users an escape hatch to your location. For example, a small button that says “change location”

If this rate is meaningful, there may be a problem with this strategy.

Wrong location solution: Add more context than only a city

If your strategy is to insert the city to a headline, it can be worth it to say “serving city and SAMPLE county.” This can increase the chance the ad is relevant for the user.

Problem: No change in conversion rate.

If you’re going to make a change like this, please test it! This is not a silver bullet.

There is a chance your conversion rate will not change.

No conversion rate solution: Add value

Being local needs to be a value add for this strategy. If there is no change in conversion rate (or it goes down!), the value of being local isn’t communicated.

Other notes

Test using the city insertion for RSA’s.

In my experience the city this shows matches the city that comes up with the value from loc_physical_ms.

This means someone will see the city in the ad copy as well as your landing page. Neat!

RIP Zipcode level business data feeds

It used to be that you could insert zip codes for individual users. Unfortunately, this is not possible anymore with the sunsetting of ETAs.

If zipcode level targeting is necessary, generate a new campaign for each zipcode. For hyper local or time sensitive services, like locksmiths, this can be worth it.

It will be interesting to see how IP address masking changes this tactic

Private Relay is Apple taking the concept of VPNs and bringing it to their users.

This feature could interfere with Google’s ability to determine a user’s location. However, Google collects plenty of location data.

The Free Solution To Insert Cities Into Your Landing Pages

This guide first covers inserting the city to your landing page for explicit searches (like “moving company Chicago”), then covers implicit searches (like “near me”)

Step one: build a spreadsheet

Build a simple spreadsheet with one column titled “city” with the cities you want to advertise for.

New York

You’ll generate a campaign using these cities to create unique ad groups, keywords ads and landing pages for each city.

For example, let’s say you’re a long distance moving company. You could make an ad group for each city and keyword variation:

  • long distance moving company + city
  • movers + city
  • best moving company + city

You will add your core words in the next step.

Step two: upload your data

Head here: and upload your data.

When you’re finished, this will generate a spreadsheet for you to upload in Google Ads editor.

You should see a screen that looks like this:

Step three: fill in your data

Start by adding the name of your ad group. The tool will generate a new ad group for each row of your spreadsheet.

If you have 500 cities in the sheet, you will get an ad group called “moving company + city” for each city.

Next add your keyword(s) for your ad group

You have the ability to create multiple ad groups for each row of your spreadsheet. Here I add another ad group for “movers + city” so I can tailor ad copy for this type of search.

Add your headline, matching your keyword

Finally, add the URL parameter called force-city=[city] to the URL. This will tell the code you install in the next section what city you want inserted.

Step four: insert the tracking code & update your website

If you’ve made it this far, congrats! We’re almost there.

In this next step you need to install the script and tell it which text you want updated.

Updating your landing page

For the text you want updated, you need to update the html tags.

For example, this is what you may have had before:

<h1>Top Rated Movers, Serving The Entire US</h1>

It should be updated to have a span tag with the data-i="location" attribute like so:

<h1>Top Rated Movers, Serving <span data-i="location">The Entire US</span></h1>

Installing the script

Install this snippet as high in your <head> tag as you can.

This script does two things:

  1. If it encounters the force-city parameter (like we showed earlier), it updates the landing page to match that city
  2. If there is no force-city parameter, it can insert the user’s city based on their real location (which I go over next)
(()=>{function e(){document.documentElement.classList.remove("async-hide")}function t(t){if(document.querySelector("body")){document.querySelectorAll("[data-i=location]").forEach((e=>{e.innerHTML=t})),e()}else document.addEventListener("DOMContentLoaded",(function(){document.querySelectorAll("[data-i=location]").forEach((e=>{e.innerHTML=t}))})),e()}!async function(){try{if(document.documentElement.classList.add("async-hide"),function(){const;if(null!==new URLSearchParams(e).get("force-city"))return!0}())return t(function(){const;return new URLSearchParams(e).get("force-city")}()),void e();let n=function(){const,t=new URLSearchParams(e);let n=t.get("loc_physical_ms"),c=t.get("loc_interest_ms");if(!n&&!c)return;let o="";return null!==n&&null!==c&&(o=""+c+"&loc_physical_ms"+n),null!==n&&null===c&&(o=""+n),null===n&&null!==c&&(o=""+c),o}(),c=await fetch(n),o=await c.json();""!==o.error?(console.warn(o.error),e()):(t(,e())}catch(t){e(),console.warn(t)}}(),setTimeout((()=>{e()}),3e3)})();

Go ahead and give it a try! You should see the URL update to have force-city=New+York+City

Top Rated Movers, Serving The Entire US

Adding support for implicit searches

Thankfully this one is pretty short!

If you’ve already installed the tracking code, you just need to add the following tracking template for your Google Ads campaign.

Now, if there’s a search like “moving company near me,” you can insert their real location.


Here’s an example:

This one shows “Medford” thanks to the url parameter


This one shows Los Angeles

Limitations of this free tool

  1. This free tool relies on a service that I pay for. I could always come down with a bad case of “hit-by-a-bus.”

Feel free to email me at if you’re not comfortable with that and I’ll hook you up.

  1. This is a client side update, not a server side update

Your page will have a slight delay in loading time with this approach. It should be in the order of a few hundred milliseconds.

A serverside strategy is best, but not accessible to everyone. That’s part of why I built which allows for server text/images side changes to any website with no code.