Category: Programmatic SEO

Programmatic SEO: Handling Search Result Pagination

Programmatic SEO: Handling Search Result Pagination

Pagination is something that should be easy, but when it goes wrong, it can really go wrong, and impact crawling & indexation.

It’s one of the first things I go to clean up, as it’s a great way to help reduce the overall crawlable pages by a site, particularly one that’s wasting their crawl budget.

Folders or query parameters for pagination?

Provided there are no tech issues that make it not possible, I recommend that query parameters are used for pagination.

Page=x is just such a clear signal to Google that its page related, and I’m all about making things clear for a robot.


Are Rel next & Rel Prev still required tags?

No, you do not need to use the rel and prev tags anymore for Google.

One of the Google engineers did a presentation in Australia, and mentioned how this conversation about the tags went.

Mueller walked in one day and essentially said “You know we’re not using these tags anymore?”, they looked at each other, and then the tags were deprecated.

Someone accidentally / unknowingly removed them from being checked and no one noticed, so they dropped their use of them.

They are still getting used by other search engines, so if Google isn’t the primary in your market, you should definitely still include the tags.


SEO Pagination best practices

Pagination best practices are pretty simple at the core.

  • Always link to the first page
  • Link to the next couple of pages, and a couple of previous pages
  • Use a clean parameter where possible, with no parameter for the first page
  • Ensure the pagination query parameter is in the canonical tag
  • Use rel next/prev tags if you want / if they’re easy enough
  • Don’t link to the final page in a series from the early pages
  • Limit page counts where possible
  • 301 redirect any page counts outside of available range back to the first page
  • Include a decent amount of results per page, 20-30, rather than many pages of fewer results


Common SEO issues with pagination

There are a handful of issues I tend to look at when auditing a pagination setup.


1. Page 1 (the default URL) has a query parameter on internal links

Some default e-commerce setups will include ?page=1 parameter on the end of links back to the first page.

By default though, this first page has no query parameter.

So you then have the following created as duplicate pages;

Exactly the same page, with exactly the same content, yet two different URLs.

Even with page=1 being stripped with a parameter, you’re actively linking to an alternate version of a page confusing Google.

John Mueller made a comment re: UTM tags on internal links, but the comment directly applies to this scenario too.

What you’re asking Google to rank, and what you’re linking two, are separate pieces of content.

Why confuse Google?

Just ensure that any links back to page 1 exactly match what you’re expecting, which would be without the query parameter.


2. Canonical tag doesn’t include the query parameter

Canonical tags must include the pagination query parameter.

Google even mentions this on their ‘common canonical mistakes’ blog post here.


3. The final page is linked to from the first page

Linking to the final page, is what every single pagination linkset does. Ever.

Why would you link to the end, when the most important results are on the first set of pages?

I always recommend removing the link to the final page in a set, and instead ensuring the first few links are available.

If Google wants to crawl all the way to page 345 it can, naturally, going page by page in the order of priority you have set.


4. Not including enough results per page

Some websites won’t use their content to its full potential. Instead, they’ll limit each page to 10 results, and just have more pages.

Bring some of that hidden content forward, to the first page.

Include more results, at least 20, maybe even 30 nowadays, and make your primary page for the search result stronger.


5. No limits on pagination

The final one here is allowing as many pages of results to be created, as possible.

Will a user ever click through to page 345?

I highly doubt it.

But a scraper will, and they’ll take all your data.

You’ll also be re-using the same set of results, over and over across the site.

By limiting the amount of pagination, you severely limit the reuse of the same listings.

IMO, this then gives the listings more value for when they’re used in the top couple pages.

Limit the pagination to what you feel is reasonable, maybe page 20, or page 50 tops, and you can start to craft crawl behavior a little more.

With pagination limited, you should 301 redirect any page outside this range back to the first page.

That will help with the initial URL cull, and will also help clean up URLs when page counts lower due to less results.



Is infinite scroll or pagination better for SEO?

Well, there are ways to make infinite scroll work. If you really want it.

However, pagination is so much easier to not only implement but to monitor and patch issues with, so it is my preferred go-to option should I be given the choice.


Handling pagination is easy

Handling pagination cleanly, and efficiently, is actually pretty easy. Once you tick a few boxes and set some limits.

The Ultimate Enterprise & Programmatic SEO Checklist

The Ultimate Enterprise & Programmatic SEO Checklist

When doing an audit, I just go through the site, flag what I see as issues, and then write them up in a Google doc.

I rarely follow the checklists.

You won’t get a giant list of “40/54,000 pages don’t have canonical tags” from me, you’ll get actionable information.

Specific issues you can just pass straight to your development team.

I thought it was time I standardised some of the checks I made, and figure these would be useful for others too.

The Programmatic SEO checklist

134 tasks to investigate a programmatic site during an SEO audit.

A non-standard checklist, this should fill in the gaps from the standard SEO items that are checked.

The majority of the items are triggers for an investigation, rather than direct yes/no checks.

Triggers for items that you should investigate, and then work out if they’re an issue.

There aren’t many simple ‘yes’/’no’ items at this level of SEO. You need to put in the hard work at determining whether what you’ve found is an issue, and whether that issue is worth fixing.

This Google Sheet checklist will point you in the direction of what to look at.

Right now, the checklist will suit search/listing type websites.

Eventually, it will suit additional types of programmatic sites as it’s built out.


How to use the checklist

You’ll find each of the items listed on a new row, with more information provided when possible.

There’s an empty space to empty your findings on each of the items.

The status column is for selecting whether an item is a Pass, Fail, or requires additional investigation.

If an item is selected as ‘Fail’, it will activate the ICE score. Read more about the ICE score here.

Some items may have the ICE score prefilled out, but due to many tasks being able to either have a low, medium, or high priority outcome the majority can’t be prefilled.

Just fill out the impact, confidence, and ease for each item, and it will output the ICE score for you.


The checklist content

The list is broken down into 4 sections, Sitewide, Search, Listings & Blog/News.

Each section has the associated tasks, with some minor duplication where it’s required across multiple sections.

The bulk of the items, but not all of them, are;


Sitewide checks

Is the site rendered server-side or client-side?
– Is the entire content SSR, or only portions?
– Are linking widgets exposed in the HTML source?
– Can Google effectively render each page?
– Are there any issues when viewing the website with JS disabled?

Is there an XML Sitemap?
– Is the sitemap broken up by categories?
– Are there sitemaps with more than 50,000 URLs or over 50mb?
– Are there 0-result SRPs in the sitemap?
– Are there query parameter filtered URLs in the sitemap?

Is there a robots.txt file?
– Does the robots.txt block any pages?
– Does the robots.txt block any resources?

Is there an HTML sitemap?
– Does the HTML sitemap have traffic in GSC?
– Does the HTML sitemap link to 0-result SRPs?

Trailing slash or no trailing slash?
– Is the non-preferred being redirected to the preferred?
– Are there pages indexed with the non-preferred option?

Are there over-indexation issues?
– Are there URLs under “Discovered – currently not indexed”?
– Are there URLs under “Crawled – currently not indexed”?
– Are there URLs under “Soft 404”?
– Are there URLs under the 3 “Duplicate” issues?
– Are there URLs under “Alternate page with proper canonical tag”?
– Are there URLs under “Page with redirect”?
– Are there URLs under “Not found (404)”?

Are there Core Web Vital flags?
– Are there FCP issues?
– Are there LCP issues?
– Are there CLS issues?
– Are there TTFB issues?

How do the crawl stats look?
– Is it primarily the primary host being crawled, or do both?
– Are there significant non-200 requests?
– Are there significant non-HTML requests?
– Are there any significant blips in the HTML crawl rate that require investigation?
– Are there any significant blips in HTML response time that require investigation?

Do any internal links contain UTM tracking parameters?

Is the site multi-national / multilingual?
– Does the URL include the country/language code at the start?
– Are hreflang tags being used on the site?
– Does the hreflang include the current page in the tag?
– Is there a language/country selector on the site?
– – Does the selector use any parameters?
– Does each language selected only have content in that language being used?

Does the brand own any other internet properties?
– – Are there any redirects, where redirects should exist?
– – Do any of the other properties link to this one?

Are there any historic URL patterns that were used?
– – Do these historic patterns all redirect?


Search checks

Does the search follow a good URL structure?
– Is what’s in a pretty URL, the best option?
– Can you re-order the URL structure and still load the page?
– Are there filters as query parameters?
– – Are the query parameters ordered correctly?
– – Are the query parameters stripped in a canonical tag?
– Are there filters that are both pretty URLs & query parameters?
– How are multi-select filters handled in the URL?
– Are search filters unnecessarily being passed through to listings?
– Are there crawlable sorting links?
– Is there any sort of customisable/combination filter layer?

Do the primary filter naming conventions make sense?
– Are there any primary filter values that could be considered ‘highly related’ enough to possibly merge them?
– Are there any primary filter values missing that should be included?

Is there a supplemental view of current results?
– Are there significant versions of the supplemental view indexed?
– Does the supplemental view canonical over to primary?

Are there internal links to other pages?
– Is there a child linking setup?
– Is there a parent linking setup?
– – Does a breadcrumb link to the correct levels?
– – Is the breadcrumb JSON schema included in the <head>
– Is there a cross linking setup?
– Are there 0-result SRPs being linked to?
– Are there links to query parameter SRPs?
– – Do these links exist in the HTML?
– Are there any unnecessary links being included on the page?
– Are there any links to URLs that redirect?

How are 0-result SRPs being handled?
– Are they getting indexed / receiving traffic?
– Do they display related listings?
– How does the behaviour change when they return to having a result?

How is pagination being handled?
– Is there a link to the final page?
– How many pages of results are being created?
– – Are pages above this max being 301 redirects to the first page?
– Is the page number included in the canonical tag?
– Are there rel next/prev meta tags being used?
– How many results are included per page?
– Do links to page 1 have page=1 query parameter?
– Does the entire page of results load SSR or is there a partial CSR load?
– Are related listings being loaded at the end of results?
– – Are related listings causing indexation issues?

Is imagery being lazy loaded?
– Are above-the-fold images excluded from lazy loading?

Is dynamic content being used?
– Are there dynamic FAQs?
– – Are these correctly marked up with FAQ schema?
– Are there any visible errors within the dynamic content?

Does the mobile view render the same as desktop?


Listing checks

Do listings follow a good URL structure?
– Are there alternate versions available via filtered URL links?

Are there internal links to other pages?
– Is there a parent linking setup?
– – Does a breadcrumb link to the correct levels?
– – Is the breadcrumb JSON schema included in the <head>
– Are links to related listings included?
– Are links included to SRPs outside what this listing suits?
– If there are multiple listing tiers, do the tiers parent/child each other appropriately?

What happens when a listing expires?
– What happens if this listing then comes back online?

Is there significant unique content for the listing?
– Is any of the listing content hidden behind read mores, tabs, or accordians?

Does the listing template automatically optimise for the keyword?

Is dynamic content being used?
– Are there dynamic FAQs?
– – Are these correctly marked up with FAQ schema?
– Are there any visible errors within the dynamic content?

Does the mobile view render the same as desktop?


Blog/news checks

Does blog content follow a good URL structure?
– Do blog posts sit within a category or other site section?

Are there internal links to other blog posts?
– Is there a parent linking setup?
– – Does a breadcrumb link to the correct levels?
– – Is the breadcrumb JSON schema included in the <head>
– Are links to related blog posts included?
– Are there links to related listings and/or categories?
– – Are these links automatic, or manually included?

Is blog content being linked to from elsewhere on the site?
– Are these inclusions automatic, or manual?
– Are the inclusions based on tags/categories, or keywords?
– Are there opportunities to extend what tag/category triggers are used so that more pages link to the content?


Access the checklist

You can access the checklist with the below link.

Make a copy of the file into your own Google drive, and then make the edits there.


Active development

The checklist is still under development, so there may be items missing that will be added at a later date.

If you have any suggestions of tasks you’d like to see added, feel free to add a comment and I will get them included.


Dynamic Variable Insertion – Scaling Programmatic Content

Dynamic Variable Insertion – Scaling Programmatic Content

I’ve been talking about programmatic SEO a little bit lately, and one of the core features of programmatic SEO is being able to dynamically insert variables.

What does this mean though? How does it work? How can you leverage dynamic variable insertion?

What’s a variable?

A variable, in this case anyway, is a piece of information pulled from a database.

Something like <ram> for a laptop. Each laptop model can have a different value for <ram>, and so it is a variable.

This <ram> could have values like 8GB, 16GB, or 32GB.


What is Dynamic Variable Insertion (DVI)?

Dynamic Variable Insertion is when you take these variables, and insert them into a piece of content dynamically, or on the fly.

It’s a key part of dynamic content generation.

Whilst ‘technically’ this is what happens when you have a table of data, or specs, DVI is really only when you use these specs within a piece of content itself.

So using the <ram> example from earlier, you could have a sentence on a product page that says something like;

This laptop has <ram> of ram installed.

After the variable is inserted, you’d have sentences of;

This laptop has 8GB of ram installed.

This laptop has 16GB of ram installed.

This laptop has 32GB of ram installed.

These variables can also be used on category/search pages, by using averages/maxs/mins/sums etc.

The average ram installed on laptops by <brand> is <ram>.

So it’s just taking a piece of data, and inserting it somewhere.

That’s all there is to it. Something extremely powerful, yet simple to leverage.

What can you do with it though? Well, that’s where you’ll need to read the other posts around dynamic content generation.

Programmatic SEO: Handling 0-Result Search Results

Programmatic SEO: Handling 0-Result Search Results

0-result SRPs are one of the main programmatic SEO issues I look into and try to clean up with clients.

Whether it’s an existing build with a large over-indexation issue, or a new build and trying to avoid it from the get-go, 0-result SRPs are something I want to patch.

What is a 0-result SRP?

A 0-result SRP is a search result page that returns 0 results.

Something that more than likely has a filter or two applied, and results in such a specific search there are no results returned.

For real estate, think about an SRP for a property type, like condos, in a small suburban neighbourhood that only has houses.

No results will get returned.

When larger sites get set up, they may have internal links that point to these pages, passing value, and sending Google to constantly crawl them.

If 0-result SRPs get significantly indexed, they can waste the crawl budget.

They will be viewed by Google as low-quality pages, which can also trigger Soft 404 errors as these 0-result SRPs will look exactly the same as each other to Google.

They’ll only have the templated elements, with no listings.


Detecting 0-result SRPs

Detecting these pages is pretty template-dependent, but you can normally crawl the site with Screaming Frog (or similar) and set up an extraction for the results count.

The pages coming back with “0 results” are what you’re looking for here.

I can go into a bit more detail later if it’s wanted.

Generally how I detect them though, is just clicking around. What templates include links to what pages. You can generally get a feel for the crawlable scale that way.


Ways 0-result SRPs get crawled

There are a number of ways these pages get discovered, but here are the top ones I audit for a client;

1. XML Sitemap

When creating an XML sitemap, rules aren’t put in place and every URL combo possible is sometimes included.


2. Internal linking structures

A good internal linking structure links from a parent to its children. Sometimes, these links aren’t filtered and you’ll get links to a number, if not all, 0-result SRPs.


3. Listings existed there once-upon-a-time

Whether via internal links, sitemaps, or expired listing redirects, there is a chance that a 0-result SRP was previously indexed due to it having links. Now it doesn’t have links though, but since Google already found it, it’s going to keep getting crawled and indexed.


Are all 0-result SRPs bad?

It depends.

The favourite answer of anyone dealing with an SEO.

Truly though, it depends on the scenario.

Are they being actively linked to, significantly indexed, and causing issues wasting significant portions of the crawl budget?

Then yeah, they are bad.

But are they rarely linked to, only indexed from old listings, and only have a few indexed?

Then nope, not an issue worth fixing… provided it stays that way.


Avoiding the initial indexing

The best way to avoid indexing the 0-result SRPs is to just avoid linking to them.

Might sound easy, but this can get a bit tricky sometimes as there are so many places to you need to add rules to.

Sitemaps, footer links, sidebar links, the list goes on.

Developers should be able to add rules to these linking widgets, so that there is a basic listing count check done, and then this added as a filter to the links.

A listing count could just be ‘has’, or ‘has not’, got listings. So true/false, and it could run live (if the developer is that keen), otherwise once a day, week, or even month could suit some times.

There have been times I’ve worked with a client and we did a once-off run for the initial build, and then they would come back and patch it 6 months later. That just ensured we got something live for launch that would still be fit-for-purpose.

Another thing you can choose to do, is set a noindex/follow tag to the page if it has 0-results. You must still ensure no links point in though.

I tend to avoid noindexing where possible, as it’s kind of a hacky avoidance patch, and is more of a fallback to doing a proper cleanup initially.


Cleaning up over-indexation

So you’ve worked out you’ve got a 0-result SRP issue. What’s next?

This is where it can get tricky.

The first step is to stop linking to them. Straight up, just remove them from everywhere by following the notes in the ‘avoid initial indexing’.

That will solve the largest part, the continual growth & value flow to these pages.

Following that you can 301 redirect the pages, depending on the scale of the issue.

Personally, I prefer to redirect them to a parent page where possible. Particularly, if the 0-result is a filter page, of another page.

ie a property type page of a location page.

That way there’s a clear parent, and the redirection would make sense in Google’s eyes.

You should definitely 301 any URLs that have no chance of having a page created anymore though. Whether through filters that no longer exist, or just changes in structure. A redirect under these scenarios should be a given.

Some others prefer to 404, or noindex, these pages to get them removed from the index. I prefer to try and avoid this, as they’re already indexed and have a little value (even if it’s minimal). I’d rather aggregate that value and send it to a parent. A no-index tag still means they’re getting crawled, so the minimum you need to do is remove all links in if you’re using a no-index or 404.

I’d rather have a 301 reversed than a 404 or noindex tag removed for a page. Have seen some severe ghosting of noindex tags before with those pages struggling to get reindexed, whereas a 301’d page seems to get reindexed pretty quickly.

Once you remove the links pointing in the majority of the recrawling should stop anyway, and so only if issues continue should you look into a more aggressive strategy for these pages.


Should you noindex 0-result search result pages?

Personally, I prefer to avoid using noindex tags on pages. I prefer to just limit their initial indexing, and then hope redirect and better-linking patches any further issues.

Many will still use noindex tags, so you can always give it a go if other solutions aren’t working.


Are they actually an issue for you?

So before you do anything else with 0-result SRPs, you need to work out one thing.

Are they actually an issue for you?

Programmatic SEO: Dynamic Content Generation

Programmatic SEO: Dynamic Content Generation

I recently wrote a post about my experience and strategies for programmatic SEO, particularly with enterprise-level clients.

One of the sections was about dynamic text generation, and I thought I would expand upon this a bit as this offers quite a bit of value to larger sites, particularly when used correctly.


What is dynamic content generation?

Dynamic content generation is exactly that. Content that is generated dynamically.

This means that content is generated on the fly using rules and variables that are available for the specific page.

There is a manual text element that creates ‘content templates’, and then using rules and then dynamically insert variables to modify the content.

The content could be paragraphs of text, FAQ-style questions, or anything in between. Some full pages of content are generated dynamically!


Using rules inside dynamic content

Rules allow you to control when you show certain dynamic elements. This will make more sense with one of the examples below, but think about it being the same as IF formulas in Excel/Sheets.

If a variable EXISTS, EQUALS, is GREATER THAN, LESS THAN, DOES NOT EXIST, etc, use or don’t use a specific piece of text.

Using ecom as an example, lets say you have laptops with dedicated or integrated video cards.

Both have their own uses, and you would want to use a different piece of content for each.

So you could use something like the below (ideally not written by me though obviously… )

If GPU is Integrated:

Due to the integrated video card, you shouldn’t expect good video game performance

If GPU is Dedicated:

The dedicated video card offers better gaming performance.

The rules let you control if and when to use a piece of content, giving you unlimited possibilities for customising usable content, provided you put in the effort to build out the rules.


Dynamic content examples

To give a better overview of what dynamic content generation is, here are a few examples.


Dynamic content generation for products from specifications

If you’re doing this on a smaller scale, then you might like this post about product description generation with AI.

However, if you’re here because you’re trying to generate product descriptions programmatically, then you might need to take a slightly different approach.

Using the same example from that post though, let’s say you have the following specs for a product in a database;

Name: Acer 14″ Chromebook 714
Brand: Acer
Operating System: Chrome OS
Processor: Intel Pentium Gold 4417U
Screen Size: 13.5″
Installed RAM: 8 GB
GPU: Intel HD Graphics 610
Screen Size: 13.5″

You could manually use these for a product description, or you could take the top specs and come up with a template description and drop in the variables.

The <name> by <brand> is a <screenSize> <operatingSystem> laptop. It comes with <installedRam> of memory installed, and there’s an <processor> processor inside.

When used for the product with the specs above, you’ll get the following text:

The Acer 14″ Chromebook 714 by Acer is a 13.5″ Chrome OS laptop. It comes with 8 GB of memory installed, and there’s an Intel Pentium Gold 4417U processor inside.

You can then use rules to extend this out, and create specifics for different ram amounts, operating systems, processors etc, and really customise it to that product set.

There might only be a small handful of products that use some sentences for the description, but that’s the joy of it. You can really hone in on the specifics and go as unique with it as you want, to really change up the products.


Dynamic content generation for real estate

There are two main types of content you can generate for real estate, with the first being listings, and the other being the search result pages.

Most listings should come with a custom description from the real estate agent, but you may choose to still generate some dynamic text for the listing. You can just follow the product example for this, as there will be different specs you can use for the listing and craft a description off that.

The one that could really set you and your competitors apart is a search result description though.

This would essentially be a summary of the listing content, available for that specific search result page.

You’d think about all the variables you have for a listing, and then work out how to essentially summarise them to use on this search page.

So what variables from the listings do you have access to, that you could summarise?

We currently have <listingCount> listings for <channel> in <location>.

The most popular property type in <location> is <popularPropertyType> with <popularPropertyTypeListingsCount> <popularPropertyType> for <channel>.

Properties range from <lowMedianPrice> to <highMedianPrice> with an average of <averagePrice>.

The top areas of <location> that buyers are looking in are <popularArea1>, <popularArea2>, and <popularArea3>.

Most buyers are looking for <averageBedrooms> bedroom properties, and are filtering by <popularFilter1>, <popularFilter2>, and <popularFilter3>.

So many more could be used, and you could use rules to make it read more natural, but the above would still be better than nothing.


Dynamic content generation for user-generated content

User-generated content can sometimes be difficult to work with when it comes to programmatic SEO.

Why? Because you don’t control what the content is you’re getting.

You can control the quality, quantity, and what they give you.

However, you can try and persuade them to give you more defined info.

Think about categories, subcategories, and tags. The more you can steer the user into giving you information, the better, as you can better understand what their content is about.

However, fret not if you only have descriptions or very limited tags.

You can create your own.

You just list out a heap of ‘seed’ keywords, along with their associated categories, and have it run through the data. When certain words are found in the data, categorise them as a specific category.

You could have many seed keywords associated with a category too.

This is extremely customisable depending on the type of content you have, but think about all the variables you have, and then use these new tags you’ve added.

Content counts, types, words they’re using in the content, anything you can use from within the content.

You don’t need every piece of content to have something. If only 10% of your content has a specific element you can use, then use it. Don’t skip it because only 10% of you’re content has something.

As your site grows, that 10% will only get larger and larger anyway, and you’ll get more content from it.


Using spintax in dynamic content

Bringing back SEO strats from 2008, you could leverage spintax to try and add additional uniqueness to your dynamic text.

Since you’re heavily using variables, most the content will be unique anyway, but the addition of spintax could add an additional uniqueness level to the overall keyword templates.

Instead of having 20-30% of your descriptions being similar, you could drop that to only 5-10% with a few template variations, or even less if you’re rolling with sentence variations that then mix up amongst themselves.

Using the product description from earlier, you could have 3 versions of that first sentence.

The <name> by <brand> is a <screenSize> <operatingSystem> laptop.

Released by <brand>, the <name> is an <operatingSystem> laptop with a <screenSize> screen.

A <screensize> laptop released by <brand>, the <name> comes with <operatingSystem> installed.

Takes me back to the fun gamey days of SEO.

Spin those together, and you can really mix things up with the content generation.


The real challenge with leveraging spintax here is ensuring it doesn’t regenerate when you change an element.

You won’t to lock in the template version selection at the first generation, to ensure that every server-side load, or on content modification, the entire content element doesn’t change.

Just moving from 1 keyword template to another, could essentially act like ‘rewriting’ the entire page’s content.

Yeah, that could be beneficial. But you don’t know.

It could also constantly change the content too. Imagine Google getting a 66% of changing the content (if you have 3 templates) of the page each time it recrawls.


Things to remember with dynamic text

Know your data

One of the biggest things to remember with dynamic text is you don’t always know the variable’s content.

There could be so many different formats of data, that you really should expect the unexpected.

Vet your database.

Make sure you know what’s going to be included.

Let’s take a look at <installedRam>.

It comes with <installedRam> of memory installed.

Is that always in the format of x GB.

Will it sometimes just be x, leaving you with ;

It comes with 16 of memory installed.

16 what?

Or could it be 16 GB memory, leaving you with;

It comes with 16 GB memory of memory installed.

Memory of memory.

Just know the different formats of your data, and you will know what to expect.


Preceding text of variables that start with a vowel

This one’s minor, but can really be the difference between human readable text, and obvious automatically generated text.

We could have <brand> that is either Apple, or Lenovo.

A <brand> laptop

Would become the following;

A Apple laptop

A Lenovo laptop

One of them works, one doesn’t.

So you either need to account for this in the template text, by ensuring no variations include templated text that could lead to this situation, by using things like ‘by <brand>’. That would ensure no scenarios like the above could happen.


Not every page needs every piece of text

You don’t need to go overboard with this. Keep it reasonable.

If you don’t have enough data for a page to use a template, then just don’t use it.

Use what you’ve got.

Wait until you have enough data for that page to use that template, and use it then.

Build this text in a way that as your business & website grows, the content grows with your automatically.


When it’s right, its right

Dynamic content can be powerful, when used correctly.

Keep it simple to start, learn what you need, and go from there.

You can build these content sections out as you go.

Generate Product Descriptions from Specs with AI

Generate Product Descriptions from Specs with AI

AI content is taking SEO by storm. Some good, some, well, not so good.

Whilst it might spit out some junk when not guided, if you give some of the AI content generators a little bit to work with then their output can be alright sometimes.

Particularly when it comes to product descriptions.

Everyone knows that you shouldn’t just use the stock-standard description by the products creator. So how about leveraging AI a little bit to generate something unique?

We can take the specs of the product, and do exactly that.

Now, the large caveat with this is you need products with a few different specs that the generator can do. This works excellent with tech products. and a few other categories.


Generating a list of specs in Google sheets

Before we can use an AI Content generate to generate a product description, we need to get a list of specs that can be inputted.

Most people will have a list of specs for each product, in a CSV or database. We will essentially take them, and then create a list of all the available features.

I’ve created a Google sheets here that you can just duplicate to get started.

We’ll be using the following formula;

=”Name: “&A2& CHAR(10) &if(istext(C2),”Brand: “&C2& CHAR(10),)

It goes column to column, and adds the product spec to a list if it exists. Essentially just concatenates them.

Each product spec will be added with a line break, if it exists. This means that some product specs might not exist, and will be excluded from this single cell.

The end result is all the product specs in a single cell.

This will make it easier to use going forward, ensuring you can create a product description from the specs list.


Generate an AI product description from a product specs list

Using this outputted list of specs, we can throw it into an AI content generate and have that generate a product description for us.

You can use the ‘generator’ sheet to keep things a bit cleaner. It’ll mean you’re not working on the same sheet as the specs list.

There are a few different pieces of AI software we can use for this, but my preference is WriteSonic.

Once you’re signed up you’ll see a heap of options on the dashboard, but just click the ‘Product Descriptions’ option.

This will load up the description generation, where you enter the product name, and paste the automated specs in.

Once it’s all entered, click Generate.

You’l be presented with 5 different descriptions to choose form

The descriptions will vary in quality, along with also vary in what specs they pull in, so pick the highest quality one and paste it back into the sheet on the ‘generator’ tab.

You’ll also find them pull in specs that you didn’t give it, as the AI will do its thing and grab them from other sources as it writes the description.

The more you give it though, the more of your own specs it’ll use.

As an example, I never gave it the mAh battery capacity, only wh capacity, so it has pulled that in, along with some other specs, itself.

You’ll want to double check all of these, as it can sometimes pull in incorrect specs.


Generate for each product

Just work through your product list, and copy paste each automated list into WriteSonic and generate a product description for it.

You can even outsource this bit to a VA, as all they will need is a little bit of product knowledge (ideally, but not required) and a decent English level.

You can merge a couple descriptions together too, if you’d like to extend a little bit.


Expand the product descriptions

You can even expand these descriptions, using the sentence expander tool from WriteSonic.

Just paste in your original description, and let writesonic attempt to write some extensions.


Using your descriptions

You can use these descriptions for whatever you want, whether it’s website copy, email, or social shares.

They might not be as good as a quality writer, but they’re performing better than just a product specs lists for me. Hopefully they work well for you!

Categorise GSC Data into Site Sections in Data Studio

Categorise GSC Data into Site Sections in Data Studio

I’ve finally started playing in Google Data Studio, and obviously kicking off by messing around with my Search Console data.

One of the initial things I wanted to do was categorise the landing page data into site sections, like I normally do in Google Sheets.

Thought you would need to create a reference table of all the URLs and their site sections, but then came across this post that gave some more advanced methods of categorising on the fly directly in data studio.


Creating a custom dimension in Google Data Studio

The first thing you need to do is create a custom dimension in Google data studio.

Click the “add a field” button in the bottom right of the data editing sidebar.

You’ll be presented with a popup which is where you can paste your site section formula.

Site Section categorisation formula

The site section formula you want to use, will be a modified version of the below formula.

when regexp_contains(Landing Page, “/laptops/|/other-folder-as-example/”) then “Category 1”
when regexp_contains(Landing Page, “/second-category/”) then “Category 2”
when regexp_contains(Landing Page, “/third/”) then “Category 3”
when regexp_contains(Landing Page, “/another/|/also-this/”) then “Category 4”
else “Unclassified”

This formula will categorise the site sections based on the text you have that is in the quotes, next to ‘Landing Page’.

You can add multiple texts for each site section by using a pipe | and that will act as an OR. So /folder-1/ OR /folder-2/ basically.

Then just change the category names to your site sections.

Extend or shorted by just adding new lines in between the ‘case’ and the ‘else’.

You will need to keep unclassified at the end, or rename it to something else, to ensure there is a fallback.

When the URL includes this and this (so includes multiple elements)

If you’d like to categorise into site sections based on requiring 2 elements, ie maybe a subdomain and a specific subfolder, then you will need the following formula instead.

when regexp_contains(Landing Page, “/laptops/|/other-folder-as-example/”) then “Category 1”
when regexp_contains(Landing Page, “/second-category/”) then “Category 2”
when regexp_contains(Landing Page, “/third/”) then “Category 3”
when regexp_contains(Landing Page, “/another/|/also-this/”) AND regexp_contains(Landing Page, “/this-folder/”) then “Category 4”
else “Unclassified”

That formula, for the last folder anyway, will ensure that either of the first 2 exist, along with ensuring that the second part also exists.


When URL includes something, but not something also

If you’d like to include specific folders, but ensure that a different folder didn’t also exist, then this is the formula you need.

when regexp_contains(Landing Page, “/laptops/|/other-folder-as-example/”) then “Category 1”
when regexp_contains(Landing Page, “/second-category/”) then “Category 2”
when regexp_contains(Landing Page, “/third/”) then “Category 3”
when regexp_contains(Landing Page, “/another/|/also-this/”) AND NOT regexp_contains(Landing Page, “/but-not-this-folder/”) then “Category 4”
else “Unclassified”

For the last site section, that will ensure one of the first two pieces exist, and that the last piece does not exist, to assign it to that associated site section.


The outcome

When you’re done, just pull the dimension in like you would normally use ‘landing page’ and it will aggregate all your data into the associated site sections.

Pretty easy was to see aggregated data, rather than just landing page level!


* Due to WordPress being WordPress, some of the formulas may not copy paste. You may have to replace the quotations, with new ones, as the styling may be affected.

Programmatic SEO: How Enterprise & Larger-scale Websites Dynamically Scale Their SEO

Programmatic SEO: How Enterprise & Larger-scale Websites Dynamically Scale Their SEO

During my time as an SEO, I have slowly but surely honed in on my specialty – Programmatic/Dynamic SEO.

It’s something I enjoy more so than regular SEO, because the smallest of change can have such a vast impact due to the sheer volume of pages being modified.

However, I’ve seen a large gap in many SEOs understanding of what dynamic SEO is, how it works, and most importantly – how to think about it.

You have to go through a different thought process when compared to normal SEO, but I’ll get into that shortly.

So let’s run through what is it, how to think about it, dynamic strategies, and a handful of examples for some inspiration.


What is dynamic SEO?

Dynamic SEO at its core is bulk optimising a website using variables/templated elements across many pages once. One change affects thousands of pages. These variables are stored in a database somewhere, that could be extended out to create the new pages.

You could be building out the system, or just optimising an existing system.

With ‘normal’ SEO, you make one change and it will affect a single page.

Dynamic SEO refers to making a single change and having it affect hundreds, thousands, or even hundreds of thousands of pages.

Imagine a car hire website, with hundreds of locations available to rent their cars from. You could have a page title of;

Car hire <location> – Deals on rental cars in <location>

Then every location page will dynamically insert their location and you’ll get;

Car hire Melbourne – Deals on rental cars in Melbourne

Car hire Sydney – Deals on rental cars in Sydney

Car hire Brisbane – Deals on rental cars in Brisbane

But then maybe you want the combinations of vehicle type in there too, you’d look at a title like;

<vehicleType> hire <location> – Deals on rental <vehicleTypePlural> in <location>

Which would give you;

Car hire Melbourne – Deals on rental cars in Melbourne

Truck hire Melbourne – Deals on rental trucks in Melbourne

Van hire Melbourne – Deals on rental vans in Melbourne

4WD hire Melbourne – Deals on rental 4WDs in Melbourne

With this being replicated across all locations & vehicle types in the database.

Another good example is a real estate website.

Imagine all the different search result pages available when looking for a property.

There are two key elements in there that should almost always be optimised for – Channel, Property Type & Location.

So if we use a page title template of;

<propertyType> for <channel> in <location> – <channelSecondary> <propertyType> from <price>

That will throw out titles like;

Apartments For Sale in Richmond – Buy Apartments from $499,000

Houses For Sale in Richmond – Buy Houses from $499,000

Apartments For Rent in South Yarra – Rental Apartments from $599,000

Units For Rent in Richmond – Rental Units from $325 p/w

Those titles use the combination of channel, property type, and location, along with a secondary version of channel to optimise for that variation. I’ve also thrown in a dynamically updated price which would reflect the lowest price from that search result and would be leveraged in an attempt to help the CTR a little.

Each of these pages would obviously have optimised content, whether it be just a search result page or whether it be some sort of dynamically optimised location page.

That is Dynamic SEO in the most basic form.


The types of websites that can leverage dynamic SEO

There’s what I feel is a common misconception when it comes to programmatic SEO, and that’s that it involves completely JS websites dynamically updating all the time.

Mostly poorly optimised, client-side JS crap essentially. And hey, that’s what I used to think because I never really understood it.

There’s so much more to it than that though!

Yeah, JavaScript websites tend to do this a lot more as they are built to allow this type of optimisation. They don’t have a core set of “pages” for the most part and just leverage a database.

So do many other websites though.

So, who could use dynamic SEO?

Anyone with a database of some sort of content. This could even be a simple spreadsheet to start.

Something that could be used to basically create a page.

My favourite example is for portals, marketplaces and classifieds websites.

You get to leverage your consumer’s & customers’ content to rank!

You don’t need to create the content. Just need to organise the DB content most effectively.

Large portions of the content on these types of websites get copy-pasted across many different websites so it just comes down to who uses it most effectively.

These sites have listing data. This data is super valuable, but not just for the listing page itself.

This data becomes valuable for the information associated with that listing.

Categories, locations, features… the list goes on!

Let’s say for a real estate portal.

A listing can rank for its address, but a term like “real estate Sydney” is silly to rank for with a single listing.

Consumers want multiple options shown when they search for that.

So, you create search result pages (SRPs).

Search result pages that are dynamically optimised because they aren’t actually “created” one by one.

Using all the listing data, you aggregate your listings based on factors that make sense to rank for.

Location – “real estate Sydney”

Property type – “Apartments”

Channel – “Real estate for sale”

Location + Property Type – “Apartments Sydney”

Location + Property Type + Channel – “Apartments for Sale Sydney”

The list just goes on.

For these larger websites, these pages aren’t created one by one. They’re set up similar to how I mentioned above, where you kind of just map the templated elements.

The listing data contains all these properties on each listing so that the URL can then be used to make the appropriate request.

A URL of /buy/sydney/ would obviously represent all properties for sale in Sydney, so that is what the database would return.

A URL of /buy/sydney/apartments/ would be all the apartments for sale in Sydney, and thus that is what would be requested from the database.

There is no /buy/sydney/apartments/ page itself, the system just knows the specific values.

These variables essentially just filter the database query that is made, to return related content.

The dynamic SEO thought process

The biggest thing to think about with dynamic SEO is that you won’t always get everything 100% right.

You will have to make sacrifices.

Sacrifices that may hinder a portion of pages, but will benefit the majority.

One optimisation that will benefit some, won’t benefit others.

You need to just think about, and optimise for, the majority.

As time goes on, you can slowly refine your strategy as you go, to lower the sacrifices that are made.

Depending on the level of site/client you’re working with will come down to what % that majority will be in the initial stages.

So you may launch something that helps 80% of the pages, great! But that poor 20 % sits off alone. Next time, you could come back and specifically tweak that 20% so that 80% of them, could be helped. Each tweak is less valuable individually, but can still help you grow overall once all the quick wins are ticked off.

What do I mean by this?

Well, let’s say you have a list of 1,000s of locations. Those location names have different lengths.

“Sydney” is a nice 6 characters long, but then the suburb of “Sydney Olympic Park” is 19 characters.

If you’re trying to come up with a single page title that allows for the lengths of both, you could be missing out on keyword/CTR opportunities for the shorter location but also be getting the longer one truncated.

Apartments For Sale in Sydney – Buy Apartments from $499,000

Apartments For Sale in Sydney Olympic Park – Buy Apartments from $499,000

Another one could be where “Apartments for sale in Sydney” is the top keyword for Sydney, but then for Melbourne, the keyword used could be “Melbourne apartments for Sale”.

You’ll have to pick one to target as your primary format.

Down the track, you might be able to tweak the system to allow for both formats. You’d also need to go through and assign the formats to each, so it’s nowhere near as simple as just picking a single format to work with.


Think about the majority

You should do an analysis of all the top keywords, work out the average format, and primarily optimise for that.

This means that you will need to make sacrifices, but just remember – you want to try to optimise for the 80%, with 20% of the effort. Keep it simple, to start.

At this level of site, page-by-page matters less than for a smaller site, especially when you’re getting started.

Once you’ve really started to take hold across the board, and there are no more ‘bulk’ changes you can do, that’s where you can focus on your more manual, page-by-page optimisations.

After a while, you could come in and do fallbacks for these titles.

So you may have one format if the location is less than x characters, and another format if the location is longer than that.

Yeah, you could do it from the start, but you may increase workloads to get all the possibilities created when they just aren’t needed right away.

You’ll also get additional buy-in from stakeholders if you can find the quick wins within your optimisations.


Optimising a Dynamic Build


The Variables

What variables do you have access to

The data points that you actually have access to, and can leverage.

For a real estate portal, this could be things like; Location, Property Type, Price, Bedrooms, Bathrooms etc

You should start by listing them all out somewhere so that you can work out if there are any gaps that you might want to optimise for.


What variables do you actually want to rank for

Based on keyword research you’ve done for the niche, you should be able to line up some of the variables you have access to, with the keyword data.

Using the real estate portal example, Location & property type are both great and a large portion of keywords will contain one, or both, of these variables.


What variables should you actually try and rank for – not all are equal

Not all variables are equal. You will get more ‘bang for buck’ with some, over others. For many variables, you will just end up creating significant amounts of crawlable/indexable URLs that will waste Googlebot’s time and offer minimal to nil value.

It’s vital to choose your variables carefully.

With real estate, you’ll have pricing, bedrooms, bathrooms, sqft and many more that just may not be what you should create pages for due to the significant volumes of variable options.

Using pricing as the example here, there are soooooo many different price filters that could be set. If a site offers 50k increments for the filter, and starts at 200k, they could go into the low millions meaning there could be 50+ variations of the single filter. This becomes large issue when you mix this with a location set of say 10,000 locations, and end up creating 500,000 price-related indexable URLs when only a handful of the keywords like ‘real estate for sale under 500k’ may be worth actually optimising for.

Similar thing with bedrooms. Yeah, 3 bedroom houses in <largeCity> may be worth it, but ‘3 bedrooms houses in <middleOfNowhereTown>’ when you have 10,000+ towns like that, along with 5-6 bedroom filter options, you’re creating 60,000+ URLs just for that single additional filter.

You can add rules to these, and create more ‘manual’ pages to target specific versions of the variables, but as a whole, anything that creates significantly more URLs that what would actually be used to rank should be avoided.


Multi-variant – multiple options

When creating pages, you could create single variable pages that could target pages like ‘houses for sale’ or ‘apartments for sale’, but many of the keywords may include two variables, like ‘apartments for sale in Sydney’.

You will need a way to allow for the creation of these pages. Not only that too, but a way to create them cleanly so that you can ideally set one as the ‘parent’ in the hierarchy to appropriately pass value around the site.


Why would too many low-value URLs become an issue?

There are a few reasons why too many URLs isn’t always a good thing, and the first comes down to crawling. Whilst Google will try and prioritise certain URLs as best possible, you will end up just wasting your crawl budget if a significant percentage of your crawlable URLs offer little to no value.

The other reason is that the content being used on these pages begins to show up on 100s to thousands of similar pages leading to Google essentially seeing duplicate pages. If it keeps seeing the same content page after page it’s may not treat it the same way, and will start devaluing these specific URLs. Then you’re left with URLs that are still available to crawl, but with minimal chance of ranking.

There are edge cases to this, particularly when you have an extremely strong domain that can hold up on its own, however, for the majority of the sites they will not be able to effectively use this content at all.


Programmatic Rules

Creating rules for the pages will significantly help a dynamic system in ranking. Rules can help stipulate what gets pages ‘created’ by limiting what content you’re linking to.

Setting up these rules will greatly benefit crawling performance as you basically say whether a page ‘exists’ or not. When it ‘exists’, you include it in the sitemap, along with internal links. This basically hides the lower value pages away in a dark hole, since you don’t want them found by the crawlers.


0-result SRPs Rule

One of the main rules I work with my clients on setting up is a 0 results rules. Google often flags 0 result pages as soft-404s, as it can somewhat understand that the page may as well be a 404 as the results are ‘not found’. When a search page returns 0 results, it should be excluded from sitemaps and links, ensuring that we don’t waste value & crawl budget on URLs that are returning ‘no results found’ type text. Google will often even flag these as soft 404 errors.


Variable-match rules

Another rule you could create would be one that only ‘creates’ pages when the variable matches one from a list. You could have say 20 property types, but maybe 5 of them are super close matches, or crossovers, of the other property types. By using a match rule like this, you could get the developers to exclude some property types from the pretty URL and instead just used them as a query parameter.


Variable to Pretty-URL Rules

Following on from choosing which variables you want to optimise for, you could set up a rule that only creates optimised pretty URLs for specific variables. ie you could create one of the property type & location variables, but not create it for bedrooms, bathrooms & filters, and instead just use a query parameter for those filters. That would ensure the user experience isn’t impacted, along with ensuring that you can cleanly cut off the lower-value filters with a canonical tag.


Graceful Fallbacks

Graceful fallbacks are used to best help you bulk optimise, but not completely stuff over the remaining 20% that may not benefit from a change you want to make.

They’re essentially just a catchall rule that is only used when another rule won’t work. It’s for the edge cases.

An easy example is a result count sentence. On an SRP you could have the text ‘We have 10 properties that match your search.”

That’s all well and good until you don’t have any. You should avoid just saying “We have 0 properties that match your search.”

It’s bland and offers both 0 value to users (… and Google).

But, a fallback could be added that was something along the lines of “We currently have no properties matching your search, but here are some highly similar properties” with either some listings included below, or a link out to related listings.

The fallback just allows you to catch that edge case, and make it a little cleaner by either optimising the content a bit, or just lining out to somewhere more appropriate for the user.

I follow a “use what you’ve got” SEO methodology.

Even if 10% of your content has a specific element you can optimise for, why limit that 10% by not using it? – other than the added time it can take of course 🙂

Just get a rule going to use it, and then use a fallback to catch & handle the other 90%. Takes time once you get to this level, but it’s well worth it to ensure continued growth.

The best thing about it is that even if say 90% need that fallback initially, as the site grows maybe it’s only 80% in a month, then 70, 60, etc. Once your rules are set up, they’ll live there forever.


Internal linking for Dynamic SEO

When optimising a dynamic site, you should really place an emphasis on a good internal linking structure. Between helping to set up a site’s hierarchy, and passing link value around the site in a more prioritised way, internal links can truly work wonders.

I wrote a bit more about my specific internal linking strategies here but the crux of it is; link through the hierarchy. Yes, links can help you prioritise pages and pass value around the site. But, at the core of any good dynamic site is the internal linking through the hiarchy. Start at the parent pages, and work your way down through the children.

Cross-link between page types when it makes sense.

Only once you’ve done the core linking strategy like that, should you look at a more individualised linking strategy that will help the key pages that may be a little deeper within the site.

Ideally, you do both at once. But ensuring efficient indexing of your setup should be a higher priority than prioritising a handful of pages in the beginning.

Finally, with linking, avoid linking to 0 value pages. This sort of setup can be built to automatically link to new pages as they get enough content to be considered a ‘page’. New content posted on the business, means new pages being created. These new pages being ‘created’ means these systems can automatically grow as the business grows.


Dynamic content generation

Ideally, you have a manually crafted piece of content for each page. When you have 10,000+ pages with a dynamic setup, that isn’t always possible.

This is where dynamic systems can shine, and a lot of websites aren’t leveraging their dynamic site to their full potential.

Using whatever variables you have that relate to a page, you could generate a dynamic piece of content to use.

One of the best examples of this is the many travel comparison websites.

ie on you’ll find expandable FAQs down the bottom.

One of them is

“How much does it cost to stay in a hotel in Sydney?”

which is essentially just

“How much does it cost to stay in a hotel in <location>?”

They give an answer of:

On average, 3-star hotels in Sydney cost AUD 273 per night, and 4-star hotels in Sydney are AUD 388 per night. If you’re looking for something really special, a 5-star hotel in Sydney can on average be found for AUD 568 per night (based on prices).

That piece of text, could be broken down into a template like;

On average, 3-star <propertyType> in <location> cost <currency> <3starAverageCost> per night, and 4-star <propertyType> in <location> are <currency> <4starAverageCost> per night. If you’re looking for something really special, a <propertyType> in <location> can on average be found for <currency> <5starAverageCost> per night (based on prices).

There would then be rules added, that if there were no 5 star hotels in that location, then just not include that sentence. So maybe there would only be 4 star hotels in a city, then only that sentence would be added.

Just don’t forget though, you could always override this dynamictext section with a manually written section when it makes sense. So maybe your top 1% pages get ‘upgraded’. Another strategy here is to use the dynamic text to kick things off, and then as pages start to gain some traction you upgrade them with manual content.

You essentially let your users decide on the content to upgrade, and to, if all goes well, continually grow a specific page.

Just don’t forget though, you could always override this dynamictext section with a manually written section when it makes sense. So maybe your top 1% pages get ‘upgraded’. Another strategy here is to use the dynamic text to kick things off, and then as pages start to gain some traction you upgrade them with manual content.

You essentially let your users decide on the content to upgrade, and to, if all goes well, continually grow a specific page.


Expanding dynamic content generation with spintax

Taking the dynamic content generation to the next level, you could also add in variations so that each version of this is a little bit more separate from the last. Essentially just a great new use for spintax.

So instead of just the single version of;

On average, 3-star <propertyType> in <location> cost <currency> <3starAverageCost> per night

You could work in the variation of;

<location> 3-star <propertyType> have an average cost per night of <currency> <3starAverageCost>.

Spintax obviously doesn’t work the wonders that it did back in 2010, but the layer of the dynamic variables within text changes things up a little bit. When you’ve got 10,000+ pages using a rather similar sentence too, mixing things up a little bit certainly can’t hurt!

However, there’s a pretty big caveat here. If you do something like this you definitely need to make sure that the text isn’t being regenerated each time the page is built. It should generate the template once-off, and then only dynamically update the variables on page build. Chunks of robotic-ish text that completely refresh each time Googlebot visits might be a nice little red flag for them.


Adding a ‘manual’ page element to dynamic builds

A programmatic SEO build doesn’t need to be 100% dynamically generated pages. You can add a more manual layer into the mix.

I lean towards calling these more ‘custom’ pages, and are essentially there to catch the leftovers that a dynamic build can’t efficiently catch.

Using the pricing filter as an example, not every price needs a clean URL.

However, top cities could benefit from having an under 300k, under 500k, under 1mil type page. So maybe 5 pages, across maybe 10 cities.

Yeah, you could work some rules into it to curtail the page creation to just what you want.

However, sometimes it might be easier to literally list out the 50 pages, and then have some sort of page filter rule to limit the content to what you want.

In this case, it could be;

Houses under 500k in Melbourne

With filters of;

propertyType = house

price < 500000

location = Melbourne (or alternatively, ‘location CONTAINS melbourne’, depending on your setup & variables)

This sort of setup would also allow the creation of pages like ‘Beachside houses in Melbourne’ if you have some sort of property feature of ‘beachside’. You might not want that created for everything, so this could be the way to maintain some flexibility.


Optimising search verse creating separate landing pages

One of the options that have come up with a couple of clients for me now, is whether we try and optimise their existing search, or create a separate landing page style setup.

Both have their own merits, with the landing page setup being great due to an easier ability to limit content should you have some sort of gating/membership type setup.

Optimising an existing search can also need a few tweaks to things like dropdown filters. A good old fashion text link has always worked the best for crawling, so additional links need to be added to make things work properly. Whereas a separate build could be a bit less ‘design-heavy’, and more focussed on initial users to get them into the system.

It really depends on tech capability too, as a simpler landing page system may be the way to go to effectively build out an MVP. You can then get it to market, and see how it performs before a larger investment can be made.


Common Dynamic SEO Mistakes

The joys of a dynamic system are that one tweak can affect all pages. It’s not hard to optimise, in bulk, so you don’t really need to hold them back too much before launching with a skeleton.

However, there are some mistakes to keep in mind with these systems.


  • Over-creating indexable pretty-URLs

This is by far the worst thing that can happen with a programmatic site build. Allowing variables to create pretty URLs that really shouldn’t be, leading to 10s or even 100s of thousands of pages being crawlable, and found, by Google that have minimal to nil value.

This can be avoided primarily via controlling what variables get pretty URLs, and what variables stick to parameters. This is due to query parameters being a little easier to control crawling of.


  • Over-indexation of query parameter URLs

Whilst these won’t tend to be linked to, query parameter URLs can still cause over-indexation issues. One of the main issues I have seen cause this, is that once one URL contains a query parameter filter, the rest of the URLs on that page may also contain the parameter to maintain similar results from a UX point of view.

At a minimum, non-pretty variables should be stripped from the URL with a canonical tag. That should limit the amount that are getting indexed, but minimising / completely avoiding links through to query parameter results will stop this issue at the root.


  • Letting crawlers run wild

Even if you’ve significantly culled the number of variables creating indexable URLs, linking through to them all can still create major over-indexing issues. Say you’ve got a variable of location, with 10,000 locations in there. Maybe only 1,000 of those locations are actually valuable enough, or even have content.

So whilst a ‘pretty’ URL may be created for all 10,000, it technically won’t exist to Google unless it’s linked to.

Ensuring you have proper rules set up on all linking widgets will help limit what is crawled, which will then obviously limit what gets indexed. This goes the same for any XML sitemaps you have. Exclude anything you’re deeming as ‘lower value’.

If you’ve run into this issue already, and are looking for a fix, 301 redirecting or 404/410ing the URLs have been the only way I have seen it efficiently patched. No canonical hack, or other trick, seems to work.


  • Forgetting to establish a hierarchy

“But a flat architecture works best”. For a 100 page content site, maybe! For a 1,000+ page website, you need to establish a hierarchy.

It best passes value around the site, appropriately prioritises URLs, sets the clear parent/child relationship between URLs that share content, and helps crawlability.

This could be via URL structures and/or breadcrumbs, along with a hierarchical interlinking system with footer/sidebar links.

The hierarchy is helpful for crawling, but extremely helpful in establishing whats what on the website, and what page is essentially a ‘filtered’ version of another page.

If you’ve got property type URLs like ‘apartments for sale in Sydney’ you really need this linked to ‘sydney real estate’ in the hierarchy. The filtered apartments page will already be using content found on the generic real estate page, so clearly showing that this page sits below the generic one will help Google understand the relationship between them.

Yeah, it probably can without setting a clear hierarchy. But why make things more difficult for Google? Make their life easy, and maybe they’ll make yours easy.


  • Not thoroughly understanding the variables at play

When you’re working with dynamic elements, they heavily rely on the actual data within the system, If this isn’t heavily vetted, or understood, you could be created content or filters that could be led stray by the data.

A simple one here is words that are plurals v singular. If you have property types that some are plurals, and some are singular, your content sentence that uses these variables won’t make sense.

Find an apartment for sale in Sydney

Find an apartments for sale in Sydney

That one little letter throws it all off, so you really need to know all datapoints of a variable to be able to work with them.

Same goes for formatting, where if some cells have a dollar sign $ and others don’t, you need to try and standarise it.

Another example is when a datapoint could contain multiple options. So for the property types, a data point could be like ‘apartments, land’ rather than the property types individually.

So you’d need to account for this by splitting them, otherwise you may end up with additional unexpected pages and/or weird wording within the content.



Programmatic SEO Examples




Without a doubt one of my favourite programmatic examples as it’s a non-standard setup.

Firstly, have a read of this post by Ryan on zapier’s SEO strategy.

The post is great, but the following point is a bit off:

But Zapier recognized the SEO value of each page having unique, relevant content.

Yeah, they recognized it. Just not from the start. Their growth exploded well before they took on the strategy he talks about to expand their unique content.

In it’s early days, Zapier really just did bare-bones pages. They used what they had, which was written purely for users.

Their original system looked like this;

Source: Wayback Machine 2012

Each specific zap has a single sentence, with the entire page’s content just being made up of these zap-specific sentences. Nothing else added.

They’ve then come in and done their first big upgrade, which included both the design, along with page-specific content & content about overall zapier.

Source: Wayback Machine 2017

This upgrade was when they really started leveraging templated dynamic text, using the variable of the software’s name.

They then upgraded a couple years later, with additional zap content being loaded in.

Source: Wayback Machine 2019


A similar transformation was seen on their more specific zap pages, where you can see the content evolve a bit more.

Early version:

Source: Wayback Machine 2014


How it’s going:

Source: Live 2022

Unfortunately can’t find a super original version of the zap pages, as it seems wayback only holds about 2014ish onwards, but even from the 2014 version we can see how basic their original zap pages were.


Whilst Zapier has improved their offering as time has passed, its crucial to remember where it began for them. They’re a great example of starting with whatever you can, and improving it along the way.

You’ve probably never heard of these guys and yet they’re one of my favourite examples of a true rules-based programmatic SEO builds.

Well, at least they used to be. Just looked at them whilst writing this up, and they’re taking a little dive. So, why not just break out a few of the things they’re doing.

Doubt it’s actually the cause, but hey, you never know!

The last great example of the I knew was from November 2020 here.

Why do I say that? Well, they had one key element:

This hideous but sexy thing provides deep links to their key category pages.

They’ve still got the header menu, but that was always there too. They just don’t seem to have the same effect that I’ve seen from these raw link widgets.

Digging into their specific category/location pages, we can see a mild but also clear difference between older and newer versions of their page.

Comparing this version to the live one here.

They’ve decreased quantities of content within each of the widgets.

Instead of 25 electricians being shown, it’s now 10.

Instead of 20 reviews, it’s 9. (however some other pages look like they have more…)

Instead of 15 ‘more electricians’ it’s 8. (again, possibly more so not sure what they’re doing here)

They’ve also updated their linking widget from the below;

To become;

They’ve essentially updated this from being highly relevant links for either the category or location, to being somewhat related by child-location types. But since these child-locations go to other categories, like plumbers, that it throws any related value out the window and just becomes a random link in Google’s eyes.

Same category, or location. These types of links shouldn’t be mixed with child locations & different categories.

Whilst there are still some extra sidebar links, these sorts of highly relevant to not-as-relevant change could impact things.


Could this be what is impacting them? Possibly, but again, these are pretty mild changes. Combined with other changes they’ve made they could all be adding up, and I’d certainly be recommending a few patches to them to try and revert a couple of items to see if they can re-acquire their former glory.

Gumtree is a staple in Australia for buying stuff, but I prefer the .com setup over the version.

Gumtree has gone the route of optimising their standard search, and has a mix of a great setup, with a slightly too loose keyword targeting strategy.

But hey, it’s working for them so who’s to judge.

Their setup starts with their homepage linking widget. With popular searches first, and popular locations second.

Clicking through to one of their cars section pages here, we can see what they’re doing with a car model page.

There are two main widgets here that really stand out for their build.

The first is their dynamic content widget;

They’re using all the magical dynamic words in there to try and pad the content, and not make it sound programmatically generated.

A similar widget is generated for pretty much every other car page too, when there’s enough content. Some widgets have less sections, so they’ve got some rules to limit what’s being used.

If we compare this content side-by-side with completely separate page we can see;

You’ll see that the questions and answers pretty much exactly match. They do seem to either rotate through questions and answer templates, with both examples have the same question, yet different answers. They then have separate questions for #2 and yet have the same answer.

Looking at once in particular, “What is the average mileage on <model> cars?”

We can see two templates they’re using;

On Gumtree, <model> cars have an average of <averageMiles> miles on the clock. To give you a guide on pricing, you can expect to pay around <averagePrice> for an average <model> on our site.


The average mileage on <model> cars is <averageMiles> miles. On Gumtree, you can expect a <model> to currently sell for around <averagePrice> on average, and the most popular years for these models are <popularYear1> and <popularYear2>.

Very similar responses, with the second one even getting a little extra added with the popular years. However, it does seem that it’s a two-sentence format, with the first being the actual miles, and the second being pricing. The popular years could just be included in that particular popular years text template. It could just be that they’re tacking an extra sentence into each section to try and pad the content a little.

They even manage to sneak some internal links into these sections, but there definitely seems a rule to it. They either aren’t able to correctly match, or just don’t, like to every variation that is mentioned within the widget. ie for colour, they link to grey, black and white, but don’t like through to yellow or green. Both seem to have enough results, so who knows.


The other widget that stands out is there footer linking widget;

All of the ‘top searches’ are highly related to the current page. Whether direct children, or similar models, they’ve done a great job of keeping these links to somewhat tight knife groups.

They seem to be pulling in top searches that fit into the matched hierarchy for the page, being the current page, parent pages, and then other children of the parent pages.


Then the ‘top locations’ tab of this widget links through to the other ‘country’ versions of this current page.

Not every page has these links, so they’ve got something setup that determines whether a page has this shown or not. It also just seems to be a handful of top locations, mixing cities/countries, rather than a proper hierarchical linking setup.

If you also go to the wales version of this page here you can see that the ‘top searches’ widget is now hidden behind an expander, and becomes very broad:

So it seems if they either can’t match it correctly, or just don’t have enough ‘sub’ results they default to a more country-wide link widget and then hide it under an expander.


One shortcut they’ve taken though, is using query parameters for all sidebar text links. Even though they’ve got an accessible ‘pretty’ URL in there system, a query parameter version still gets linked to from the sidebar.

So even though

exists, the ‘black’ selector from the sidebar will link through to;

This would definitely be impacting crawling, and potentially causing them issues, but they’re Gumtree. This stuff can pass pretty easily for them.

If you’re looking to jump into a contested market, you should definitely try and avoid a situation like this. It certainly won’t help  you.

I tend to recommend that clients should link to the pretty URL version of a page all the time, to avoid these issues.

At minimum, when only a single parameter exists and it has a pretty URL, it should be redirected to that pretty URL, but even that still doubles crawling for what could be seen as key pages.

It becomes a little messy, and highly modified on a case-by-case basis, when a multi-select filter is at play where multiple options can be chosen.

They’re less likely to cause as many issues, as they tend to not be linked to as much as single option filters.


Wrapping it up

Programmatic SEO builds can come in all shapes and sizes, but they’re all coming back to one thing at their core – leveraging data.

You need to change how you think about SEO, to be able to work with these types of sites.

You can’t just deliver 10,000 page titles in a spreadsheet for a dev team to implement. But hey, I’m sure we’ve all tried!

Once you get over the initial step in thinking, you will realise how the large sites develop and grow their strategy.

Internal Linking Strategies for Programmatic / Dynamic SEO

Internal Linking Strategies for Programmatic / Dynamic SEO

Internal links are important. Unless you’re just starting out in SEO, this should be known as a fundamental part of optimisations done to ANY website. Whether a little local business site, a niche content site or a larger scale, dynamic/programmatic site like portals, directories or marketplaces, it’s important for all types of websites.

It’s one of the main elements I’ll look at with clients, and they’re often overlooked at scale. It’s surprising how easy it is to get some quick wins by just adding a link widget though.

For programmatic sites, you should have 3 types of links built into your template so that they’re ‘automated’;

✅ 𝐏𝐚𝐫𝐞𝐧𝐭 𝐥𝐢𝐧𝐤𝐢𝐧𝐠

The ‘up-the-hierarchy’ links, and are easily accomplished via breadcrumbs. In addition to a well laid out site structure, these breadcrumbs help set the hierarchy to your site via helping to ‘parent’ content, which helps ensure your main content gets the value from its ‘child’ pages.

So a location page could link up to its parent category.

✅ 𝐂𝐡𝐢𝐥𝐝 𝐥𝐢𝐧𝐤𝐢𝐧𝐠

Essential to passing authority down the site structure, these links are also extremely important to help Google crawl through key pages. These should link to pages that sit below the current page.

I recommend these are accomplished with footer/sidebar style link widgets, with filters applied to them to ensure only important / priority pages are included. This helps maximise the usage of your crawl budget, essentially just avoiding wasting Google’s time.

A parent category could link through down to its key location pages. In some cases, it could link to a region-type page, with the region-type page linking through to individual locations.

✅ 𝐂𝐫𝐨𝐬𝐬-𝐥𝐢𝐧𝐤𝐢𝐧𝐠

Also be known as related page linking, these links link across to similar pages. These links help connect similar pages together that may sit within a separate part of the site.

The links could be to pages within the same category but nearby locations, or the same location but in a different related category.

If you’re missing one, or all, of the above links then you should look at kicking them off asap. These can be extremely easy to integrate, and may actually show measurable impacts alone due to their importance.

Just keep in mind though, there are always risks with something like this done at scale. Automated widgets like these could expose URLs with issues that may not have been crawled before, or high quantities of low-value pages (ie 0 results search pages). Just make sure you’re adding some rules/intelligence/filters to the widgets, along with significant crawl-testing, and you’ll be good to go.

Product Comparison Keywords: A foot-in-the-door SEO strategy

Product Comparison Keywords: A foot-in-the-door SEO strategy

Comparison keywords are an awesome foot-in-the-door SEO targeting strategy if you’re kicking off any sort of product-based strategy.

Many decent volume, low-comp keywords just sitting there for the picking and can be targetted individually, or in bulk.

Many people won’t even consider many of them!

My latest little project has even just cracked 270 clicks a day on the comparison pages alone… within 2 months.

Not a bad little start!

Comparison keywords search performance

As with all keywords though, there are some that are easier than others.

How do we find the keywords?

How can we best target them to make the most of the opportunity?

Who’s doing it well?

Before we get stuck in and take a look at a few options, I just want to explain a little about these comparison terms.


What are comparison keywords?

As the name suggests, they’re simply keywords that a consumer will search when they’re looking to compare products.

Two of the main comparison keyword formats you’ll see are;

Product 1 vs Product 2

Product 2 or Product 3

And then now and then, you’ll find yourself an elusive three-way comparison that could be worth targeting;

Product 1 vs Product 2 vs Product 3

But, what can we deem as a “product” when it comes to these comparisons?


These aren’t limited to products of the standard physical nature found in a store.

Which leads me into who can target these comparison keywords.


Who can leverage product comparison keywords?

Many will initially think Laptops, Tablets, Phones etc and all your other gizmos, gadgets and anything you walk into a store to buy.

But they go so much further than that.

Affiliate marketers, media companies, business owners.

There are plenty of options to jump into the comparison ring and knock out some rankings.

So let’s take a look at a few of the options.


Ecommerce / Traditional Product-based Websites

The traditional ecom / product-based websites are the default go-to for the usage of comparison terms.

Whether selling laptops or washing machines, phones or vacuums, cars or blinds, consumers are probably looking at comparing that product to something else before they buy.

Someone looking at grabbing an XPS laptop could be searching;

Product comparison keywords example 1

Albeit a smaller volume, you’ve also got the category/subcategory/type comparison keywords that fit in here, with keywords like;

Product comparison keywords example 2

These have a much-limited scope, so normally are reserved for these higher volume product-based comparison terms.

However, still worth looking into their value for you.


SAAS / Software Businesses

Many software companies get stuck with where to start their SEO strategy.

Most will tackle a content strategy, filling up their blogs with general content that fits their niche.

Which is great! But… they’re missing out on potentially closing an audience that’s a bit further along their funnel.

Users that are just doing some final comparisons before they pull the trigger on their chosen software.

Wouldn’t you want to ‘sway’ the conversation with some favourable data-points showing you as the #1 choice?

Let’s check out what people might compare one of the top mailing software with…

Product comparison keywords example 3

But guess what? Mailchimp is nowhere to be found for these keywords…

Except for one.

Mailchimp comparison example

Klaviyo is also running the comparison back to them.

This is the only comparison they appear to be running.

Mailchimp is leaving out so much opportunity where they could be controlling some of the comparison conversations for the other comparisons too.


Service Providers

Looking at a new electricity provider? Or a new phone company?

What about a new internet plan?

Well, even if you’re not, there are thousands of people that are, every single month.

Product comparison keywords example 4

What about a new web hosting plan?

Product comparison keywords example 5



Looking to move house?

What about planning your next holiday?

Once you lock down a few options, you probably wanna weigh them up against each other to see where could be best for you.

Product comparison keywords example 6

Websites in travel could really be getting in on this to grab some potentially easy conversions.

Even the official tourism groups of the locations should be jumping on this, to try to swing it in their favour.

One big callout here though, be careful of sports teams, or other things that use the location name in these comparisons. Your volumes will be thrown out the window.

A quick Google search can confirm Google’s intent from the keyword, and avoid you wasting your time.



This is one of the categories where things get interesting.

A majority of the volume for sports-related comparison terms will come down to users trying to find out information about an upcoming/completed match between the teams.

However, there is one other big share of this market that is worth taking a stab at.

Consumers search these keywords to work out who could win, should they ever play against each other.

Some random American hockey team still sits at some pretty high volume;

Product comparison keywords example 7

One even includes ‘tickets’ which can show the intent here.

Correct targeting by a sports team could help them grab some of the SERP real estate for these keywords.

Correct targeting by a sports website, could even steal some keywords from the larger players.


General Businesses

You really start scraping the barrel here, due to the localised nature of general small businesses.

But, the keywords are still there. Hiding away, waiting for you to find them!

Product comparison keywords example 8

Never know, your business/businesses in your niche, may have some comparisons waiting for you to leverage.


Finding the keywords

How do we actually go out and find the keywords though?

There are two tools I use for this, but both involve a little pre-generation of your seed keywords.

It all starts with a list of the products you want to compare.

If you’re only looking to try find comparisons for a single product, or a single name, it’s easy!

Just do;

$name$ vs


Product name vs

You can then try to look at any variations of the name.

For a basic product, I’d start with

$brand$ $productName$ vs

$productName$ vs

That get’s whacked into the tools, and hopefully, you’ll find yourself some nice comparison keywords to play with.

However, for the people that are looking to find comparisons they could do, from a larger list, you need to;

  • List out all your product names in Google sheets
  • Add any variations to the list
  • Append “vs”, “verse”, “or”, or any other extension you’d like to search for
  • Copy all into a single list

This can all be done pretty quickly in Google sheets;

Generating product comparison keywords with Google Sheets

From here, we just need to paste the ‘C’ column somewhere, to remove the formula and avoid mishaps.


Finding comparison keywords with ahrefs

Being one of the obvious larger keyword research tools around at the moment, ahrefs offers something that many tools can’t.

More keywords!

Which is exactly what we need for this.

ahrefs has a ‘phrase match’ keyword research option, which will return any keywords in their database that contain the inputted seed words.

Just access their keyword explorer, paste in 10 seed keywords (their max for phrase option) and then click “phrase match”.

ahrefs phrase match example

This will hopefully come back with plenty of the top comparisons for you to look at!

Using my XPS example, I can see that I should potentially be looking at creating comparisons for hundreds of different combinations!

If you’re working with some higher volume products, you’ll find plenty of comparison duplicates, with alternate names.

Read on for something I’ve shared below, to help analyse your list.


Finding comparison keywords with Google Suggest/Autocomplete

The other method of finding comparison keywords is to use Google’s autocomplete feature.

Google autocomplete suggest

This will give you hot comparisons to use. Hyper dynamic keywords, that will popup well before any keyword research tool’s database will grab them.

Yeah, my example doesn’t do this justice though, as the XPS is a popular laptop!

But how about a less popular model.

If we take a look at one of Asus’ newer laptops, one I am actually hoping to buy as soon as Australia has some more stock, we can see a different story.

ahrefs phrase match

Google suggesting comparison terms

Look at all that magical autocomplete data!

ahrefs had nothing.

I wouldn’t expect it too either. It sometimes takes months and months before keyword tools will collect see these keywords.

Simple typing the product names into the Google search bar is a quick and dirty way of grabbing these terms.

However, I prefer to use a tool as I can grab some search volume in the process, should it be available.

Keysearch is a tool I’ve used for a couple of years, primarily because they come out with some awesome discounts now and then, and have decent enough data for it.

Type in the keyword, one at a time for autocomplete usage, and then click ‘Google suggest’.


Filter the keywords to contain your comparison phrase, in this case, it is ‘vs’.

It will then spit out the same autocomplete keywords as before, and a few more, for you to get stuck into.

Repeat the process for each of your seed keywords, and it will give you the comparison terms along with any volume or CPC data the tool has.

If you’re really not fussed about the extra data, jump into Keyword Shitter and throw in all your seed keywords at once.

keyword shitter comparison keywords

Add all your comparison phrases in as positive filters and then you can go ahead and keyword shit yourself silly!


Zero search volume does not mean zero search volume

Keyword search volume is derived as an average of the previous 12 months of searches for that keyword, should tools actually have that data.

When products are released, it could take months before a tool even shows the first month of volume for it.

Any comparison you’re doing for a new product is pretty much guaranteed to have no volume.

You will also find many comparisons that will show zero volume, even though they are older.

Due to the lower volume, lower comp, nature of these keywords it could still be worth creating the comparison.

Considering how easy some of these pages are to create, even if it just helped make 3-5 conversions over a 6-12 month period, what’s that worth to you?

For some, it’ll be worth plenty.

Need proof of their value? Fine.

Here are some stats of a single, shiny comparison page;

74 total keywords showing up in GSC for this page, with the top one being almost 50 clicks, over the 6 week period.

How do these keywords look in ahrefs though?

Like absolute garbage – as expected haha.

Ahrefs didn’t even have 2/3rds of the keywords in their database!

Two keywords show a whopping 30 combined volume, yet they’ve driven a combined ~200 clicks for the month.

Rarely, will someone target a set of “zero volume” keywords because of this.

Comparison keywords are where I’d recommend that be a bit different. They’re worth the “zero” volume.

That’s because that zero search volume does not mean zero search volume.


Matching & extracting the product names from the comparisons

If you’re working in bulk, the generated keywords can sometimes be a bit of a pain as you might struggle to match up the product names.

There could be many names for a single product, and individually matching these would be painful if they’re across lots of comparisons.

Well, it was a pain for me anyway – so maybe this will help you out too!

Duplicate My Google Sheet Below

It’s a bit of a behemoth… but I wouldn’t have bothered doing it if it wasn’t going to turn out that way 😛

1. Paste in all your keywords & volumes

2. Scroll across to the right and paste in your product seed words, along with their associated product names & IDs

The ‘seed’ is a word/phrase within the keywords, that would align it to the specific product. So for me, ‘xps 15’ relates back to the Dell XPS 15.

3. Drag down the formulas, into any empty rows you have

The formulas will now run and match any products within your comparison keywords, to the seed list you provided.

This is a two-step process, where you’ll find that ‘model 1’ and ‘model 2’ will be broken up by either “vs”, “verse”, “or”, or “compared to” as the comparison text in the middle.

If the comparison keyword doesn’t contain one of them, the formula will break. You should be able to adjust the formula to suit your needs, and if not, just comment and I will try help you out 🙂

Once broken down, the formulas will categorise the two models, using the seed keyword list you provided. It will just look for the seed, inside the keyword, and then match it up with the given product.

If the keywords aren’t being matched to the products, you will need to build out your seed list to include the missing seed words. This means you’ll just need to add the alternate names for a product, until the formula can correct match them together.

Model 1 assumes that you know the exact model name before the ‘vs’ because that’s what you would have been researching.

However, model 2 tries to match two different ways.

There’s the same ‘exact’ match of the seed as Model 1, but then there is also a partial match.

If I delete the seeds for ‘xps 15’, and ‘xps 17’, you’ll see that the partial match still matches these to keywords to their correct model.

This is because the partial match formula is based on a wildcard match, and will match ‘xps 17’ inside the seed of ‘dell xps 17’.

The final column will then look for an exact matched product, and if one isn’t there it will look for a partial match.

Sometimes the partial match can go haywire though, so that’s why it’ll prioritise an exact match where possible. It’s also best if you manually check the partial matches, as you never know what it’ll match up to.

Duplicate My Google Sheet Below

Prioritising the comparisons

If you’re only working with a few comparisons, just stick to however you normally prioritise SEO stuff. Usually just by a mix of search volume & competition.

But, if you’re working in bulk you’d probably be better off running your keywords through this sheet.

Provided you’ve done the above instructions on setting up the sheet, you’ll just want to load up all your product names, with their combined search volume on the far right. Whether this is volume from one keyword, or many, it just needs to be one total volume per product.

The sheet will pull in this product volume data, and display it next to the match model names.

And this is where things get interesting.

The formula in the sheet, will look at the volumes for the two products being compared, and then optimise the ordering of the comparison to ensure the highest volume product is first in the order.

Might not be helpful to everyone, but it was something I wanted to use, so you get it too 🙂

In the above, even though the XPS 13 came first in the keyword, the dataset says that XPS 15 had a higher volume, thus putting it first in the calculated comparison.

You can just kill off the search volume for the products if you don’t want to use this feature.

Individual comparisons will then be prioritises by their search volume with the ‘comparison volume’ column aggregating the search volume of any comparison keywords with their associated matched comparisons.

All the duplicate comparisons will have their search volume aggregated from the unique comparison keywords that were matched to them.

Search volume for any time XPS 15 was compared to XPS 17 gets aggregated into the “Dell XPS 15 vs Dell XPS 17” comparison.

You’ll then be able to sort all your comparisons by volume, to work out what to target first.

Duplicate My Google Sheet Below

How to properly target comparison keywords

I’ll keep this bit brief, as you’ll see a few different ways to target them below. Also cant give you alllll my secrets 😉

There are two mains ways to target them though.

Dynamically and manually.

Dynamically will leverage a dataset and let you target the keywords in bulk, giving you the option to build out and optimise the content further as they grow.

Manually means you’d be writing out the content for the pages individually as you go.

Both have their own merits, but if you’re looking at targeting more than a handful of comparisons at a time, some sort of dynamic solution would be best.

No matter the strategy you’re taking, there are a couple of things that should really be included in these comparison pages.

A nice and simple table/chart showing a direct comparison of any features/specifications of the products, and then a summary of the strengths and weaknesses of each product off the back of these.

At its core, that’s what you’d need at a minimum. The rest is SEO.


Good comparison examples

Who does this well?

There are soooo many examples of comparison pages – particularly in tech.

The best examples, are looking at the keywords you’re trying to target though. Nothing better than leveraging what Google already loves, for what you’re targeting.

You don’t need to be as good as the overall best, you just need to be better than your direct competitors.

Apply some of what you can learn from the overall best to your market though, and it should help you out!

These guys are definitely one of the “best in class” comparison websites… you’ve probably never heard of them though!

Tech, Sports, Food, even dating apps!

423k out of their total 493k keywords are rankings for URLs with “-vs-” in them.

That’s their comparison pages.

They’re absolutely killing it.

versus comparison example

They are definitely one of the “prettier” comparison websites floating around and give some great breakdowns of the individual features of each device.



Can you even guess what they compare? Yeah, cameras, and they’re killing it too.

Not as high as they used to sit, but they’ve managed to keep themselves pretty stable over the last couple of years.

CameraDecision example

They’re just keeping it simple though.

Overall summary, key specs of both, and then the side-by-side features comparison.

These guys do a lot more than comparisons, but they’ve got some great comparison pages here!

rtings example

Simple summaries, with some awesome side-by-side comparisons of specs and features.

Not much text, but they’re covering that on their reviews side. These are just their pure reviews.

They’re ranking well with them too!



Webhosting is a tough niche to crack. There are some prime commissions available for those that do though!

Host advice example

Bit of a slap from the May update it seems though!

These guys have cracked one of the largest web hosting comparisons they can – Godaddy.

HostAdvice comparison example

They’ve covered so much here, but as you’ll see, it’s just a giant comparison table!

A lot of work goes into the data powering this page, but at its core, it’s just that – data.


Why wouldn’t you target comparison keywords?

There are a few reasons I know of, of why people might not target these keywords. All completely understandable, and up to you if you see them as blockers.

But hey, you never know until you give things a go sometimes!


You don’t like free traffic from brand jacking

Has anyone… ever… turned down highly targeted free traffic before?

Probably, but I wouldn’t be. I’d be milking that traffic as much as possible!

Comparison keywords are great for when people are looking for those comparisons, but, there’s something that I haven’t mentioned yet.

These pages will also rank for non-comparison terms.

Imagine being a brand new email platform, creating a comparison of you vs MailChimp, but then ranking for keywords like “MailChimp features”, “What is MailChimp used for” or even “MailChimp cost”.

This is known as brand jacking, and it’s a great way to get your brand in front of a highly targeted user-base!

You probably won’t be able to jump out the gate with such a known brand, but there are definitely some competitor terms you could get in there with, stealing yourself some nice SERP space.

Brand jacking is also a perfect segway into the next reason…


Legal stuff

Probably one of the biggest is the fear of being sued. If you’re outright comparing yourself to your competitors, and it’s favourable for you, they’re obviously not going to like it.

They’re especially not going to like it if you’re ranking at the top of Google for keywords including their brand name, or worse, their brand name by itself.

I have pretty much no clue about this side of things, so anything I say about this stuff is further from advice that it could possibly ever be, but what I know is you must avoid anything slanderous.

Stick to what you know. Talk yourself up, but don’t slander or negatively talk about the competitors.

Let your numbers & features do the talking.



Users will often prefer third-party, unbiased reviews.

If you’re not third-party and you’re just comparing yourself to competitors, consumers may not take to that favourably.

However, it’s still worth jumping in there with your say. Something is better than nothing!


Lower volume markets

The volume is so low, it might not be worth the effort for some.

Yeah, this is completely reasonable.

But, you never know until you try!

At least dig in, see what you can find, and give it a shot. Do a test run with a few, see how they perform, and go from there.


Unknown brand

Following on from lower volume markets, if you’re a brand new SAAS and no one knows your name, you won’t benefit from these comparison terms like others will.

Why? No ones searching your brand, so no ones searching for comparisons.

As you grow, they will though.

And if someone comes across you, they might want to see how you’re the better option anyway, so I’d say it’s still worth getting in early here.

You might even just rank for the competitors brand names without anyone searching the comparison anyway 😉


What’s stopping you?

Don’t see the value?

Can’t find any comparisons you’d want to target?

I’d love to hear if there are any reasons holding you back.

Hit up the comments with any comparison feedback, especially if you’re successfully targeting them already!