Local SEO - Structured Data - Tag Manager

How To: Do Local SEO for Multiple Stores Using LocalBusiness Schema and Google Tag Manager

By on 16th November 2021

Reading Time: 6 minutes

  • LinkedIn
  • Twitter
Cows

Following a migration and site launch 12 months ago, I have been working with the country store chain Mole Valley Farmers to enhance their organic visibility and drive more relevant traffic to the site.   In this time I’ve carried out various optimisations including site speed, core web vitals, category page optimisation and dynamic product page optimisation.

As well as an online presence, Mole Valley Farmers have over 50 country stores nationwide so optimising Google Business Listings and individual store pages is a must for local search, in particular a wide range of “near me” searches.

However, optimising 50+ individual business listings and pages is going to be quite time consuming if we were to do this on a store by store basis.

So, we took to the following steps:

1) Managing Multiple Google Business Listings

Fortunately for me, the client already uses UberAll, a tool which allows you to manage business listings in bulk across a number of local listing platforms including Google Business Listings.  It also allows you to easily import and export store data which is key to what we want to achieve.

In terms of Local SEO and business listings, I tend to follow the following steps (beyond entering standard business info) when optimsing a listing:

A) Implement a non spammy brand name for your store. 

Avoid keyword stuffing.  For a site with multiple stores such as this, I’d go with:

Brand Namelocation

e.g.

Mole Country Stores – Alnwick

B) Amend the page URLs to include the following UTM parameters:

?utm_source=googlemaps&utm_medium=organic

e.g.

https://www.moleonline.com/storelocator/index/store/0/alnwick/?utm_source=googlemaps&utm_medium=organic

this then allows you to track how much traffic you get via organic map listings in search:

source / medium

2) Create A Master Spreadsheet with All Store Data

Once you have exported/compiled your multiple store data you can put this into a spreadsheet which contains the following data used to optimise listings:

  • ID / name (basically, the store location)
  • Website URL
  • Google Map Listing URL
  • Business Listing Name
  • Website Address
  • City
  • County
  • Postcode
  • Country
  • Phone Number
  • Email
  • Latitude
  • Longitude
  • Opening hours
    • This is split across two columns for each day to show the opening and closing time

You should then end up with a file that looks something like this:

spreadsheet data

Before we import this data, we need to be able to identify each store in Google Tag Manager.

3) Set Up A Custom Variable To Identify The Store Page

First of all, we need a way to identify each store page individually, for that, we will use the H1 tag.

Using the inspector tool, we can get the CSS Selector path:

CSS Selector

Which we then use to create a custom variable called “H1 store name” which is of the variable type “DOM Element” and Selection Method is “CSS Selector” as follows:

custom variable

Then, as you navigate each store page you can see the variable populate within Google Tag Assistant:

Google Tag Assistant

Now we know what store we are on, we can use this to pull in the relevant store data:

4) Import Store Data Into Google Tag Manager via Look Up Tables

In simplistic terms, Look Up tables are a mini database which we can use to associate data with a specific input – in this case, the location name.   For every column in the spreadsheet, we can associate the location name with the website URL, city, postcode, map listing URL etc.

Once populated, they will look like this:

Note: the input variable is the name of the custom variable we set previously:

{{H1 Store Name}}

So when “Alnwick” is passed in, the variable {{Store – URL}} is set to output accordingly

Again though, creating look up tables for 50 stores each with 28 unique properties is a real pain in the arse if you were to do it manually.

But you don’t need to.

If you don’t know already Simo Ahava is the Godfather of all things tag manager, so it should come as no surprise that he’s come up with a relatively quick and easy way to create large look up tables.

Follow this link to find out how to do it

When you’ve got to grips with that, you will find yourself using Google Sheets as follows to create and populate your tables:

populated table

Once you’ve done that for each property / column in the spreadsheet, you have a data set contained within look up tables we can use to populate a localBusiness schema template:

user defined variables

Then when you navigate to a store page, you will see the variables are populated according to the location variable set by the H1 tag:

Populated variables

5) Create A LocalBusiness Schema Template

You can find out more about LocalBusiness Schema via JSON and what properties to use here but here is a copy of the template I’ll be using:

<script type="application/ld+json">
{
	"@context" : "http://schema.org",
	"@type" : "LocalBusiness",
	"name" : "{{Store - Name}}",
	"url" : "{{Store - URL}}",
	"logo": "https://moleonline.com/media/wysiwyg/mole_valley_logo.png",
	"image": "https://lh5.googleusercontent.com/p/AF1QipNg3sC47D2PVbLuFqJysbvyG5P21U2ccR2SiShT=w426-h240-k-no",
	"hasMap": "{{Store - hasMap}}",
	"telephone": "{{Store - Telephone}}",
    	"email": "{{Store - Email}}",
	"address": 
	{
		"@type": "PostalAddress",
		"streetAddress": "{{Store - Street Address}}",
		"addressLocality": "{{Store - Locality}}",
		"addressRegion": "{{Store - Region}}",
		"postalCode": "{{Store - Postcode}}",
		"addressCountry": "UK"
	},
	"geo": 
	{
		"@type": "GeoCoordinates",
		"latitude": "{{Store - Latitude}}",
		"longitude": "{{Store - Longitude}}"
	}, 		
	"openingHoursSpecification": 
	[
		{
			"@type": "OpeningHoursSpecification",
			"dayOfWeek": 
			[
				"Monday"
			],
			"opens": "{{Store - Mon Open}}",
			"closes": "{{Store - Mon Close}}"
		},
		{
			"@type": "OpeningHoursSpecification",
			"dayOfWeek": 
			[
				"Tuesday"
			],
			"opens": "{{Store - Tue Open}}",
			"closes": "{{Store - Tue Close}}"
		},
		{
			"@type": "OpeningHoursSpecification",
			"dayOfWeek": 
			[
				"Wednesday"
			],
			"opens": "{{Store - Wed Open}}",
			"closes": "{{Store - Wed Close}}"
		},
		{
			"@type": "OpeningHoursSpecification",
			"dayOfWeek": 
			[
				"Thursday"
			],
			"opens": "{{Store - Thu Open}}",
			"closes": "{{Store - Thu Close}}"
		},
		{
			"@type": "OpeningHoursSpecification",
			"dayOfWeek": 
			[
				"Friday"
			],
			"opens": "{{Store - Fri Open}}",
			"closes": "{{Store - Fri Close}}"
		},
		{
			"@type": "OpeningHoursSpecification",
			"dayOfWeek": 
			[
				"Saturday"
			],
			"opens": "{{Store - Sat Open}}",
			"closes": "{{Store - Sat Close}}"
		},
		{
			"@type": "OpeningHoursSpecification",
			"dayOfWeek": 
			[
				"Sunday"
			],
			"opens": "{{Store - Sun Open}}",
			"closes": "{{Store - Sun Close}}"
		}
	],
	"sameAs" : 
	[
		"https://www.facebook.com/molevalleyfarmers/",
		"https://twitter.com/molevalley",
		"https://www.youtube.com/channel/UCMiUx9-x5oTJ2FlTpO_iB6Q"
	]
}
</script>

This uses the lookup table variables set above to populate the various properties.  As the logo, image and social media profiles do not change, I have hard coded these values straight in, but you can use as many look up tables across as many properties as you like.

Once you’ve created your tag you need a trigger to fire when you are on a store page:

custom tag

You could use a variable that checks if the H1 Store Name variable is not null, but in this case I’ve just gone with the URL path:

store page

And when that fires, the custom schema template will be injected into the relevant page.

You can test all is well via the schema mark up validator:

schema mark up validation

So What Happens Next?

Well, after going to all this effort you’d hope to see an increase in impressions and clicks to your optimised-for-local-search store pages.  That’s what happened to Mole Online anyway:

See if you can spot when this was all implemented:

traffic spike

If we compare before and after, we see a significant increase in numbers to store pages:

compare store pages

As well as a better CTR for “near me” queries:

compare near me queries

I can’t share GA data but trust me, actual organic traffic, transactions, conversion rate and revenue all went up to.

In Summary

LocalBusiness Schema is good for SEO when it comes to local search and near me phrases.

If you have lots of stores, then use GTM to add schema across all pages using one custom tag and look up tables

This leads to happy clients:


“Dave is an excellent person to deal with, he offered tremendous support during our recent website migration and his thorough and knowledgeable support meant that we quickly saw significant improvements in search rankings. His ongoing support and detailed reporting provide insight and guidance as we continue to make improvements to performance.”

Brian McArdle Brian McArdle
moleonline.com

Get In Touch

Fill in the form below if you want to enhance your website's organic visibility