Tag Manager
Hashbang URLs and SEO: What You Need to Know
TL;DR:
Hashbang URLs use #! fragments to represent dynamically loaded content and were once common on AJAX websites. Google deprecated its old AJAX crawling scheme years ago, and I wouldn’t use hashbang URLs today for content that needs to rank as separate pages. If an older website still uses them, first establish what Google is actually indexing and whether the content has existing search value, then consider migrating important content to conventional crawlable URLs.
Why I originally encountered hashbang URLs
Hashbang URLs were once commonly used by AJAX websites to load different content without requiring a traditional page refresh.
You’ll recognise them by the #! within the URL:
https://example.com/services/#!/location-a
I first encountered them while working on a website that used AJAX to generate dozens of location pages. At the time, I ended up using Google Tag Manager and JavaScript to work around some of the SEO problems the setup created.
I wouldn’t recommend that solution today.
Hashbang URLs are largely a legacy approach, and if you’re building or restructuring a website now, there are better ways to create crawlable URLs for dynamically generated content.
However, they still exist on older websites, so it’s useful to understand what hashbang URLs are, how search engines treat them, and what to do if you discover them on a site you’re working on.
What is a hashbang URL?
A hashbang is the combination of a hash and an exclamation mark:
#!
It was historically used by AJAX applications to represent different application states or dynamically loaded content within a URL.
For example:
https://example.com/services/#!/location-a
https://example.com/services/#!/location-b
https://example.com/services/#!/location-c
To a user, these can appear to be three different pages because the content displayed in the browser changes for each location.
The important SEO issue is that the part after the # is a URL fragment, rather than a conventional URL path.
That’s very different from having genuinely separate URLs such as:
https://example.com/services/location-a
https://example.com/services/location-b
https://example.com/services/location-c
Why were hashbang URLs used?
Hashbang URLs became popular alongside AJAX websites and JavaScript applications that could change the content displayed on a page without loading a completely new HTML document.
That created a problem for search engines. Different content could be displayed to users while the underlying page URL remained essentially the same.
Google introduced an AJAX crawling scheme that used #! URLs to help make this dynamically generated content discoverable. Websites could provide an alternative version of the content that search engines were able to crawl.
For example, a site might use:
https://example.com/services/#!/location-a
The approach made sense for some JavaScript-heavy websites at the time, but it was a workaround for the limitations of search engines and web technology of that period.
Google deprecated this AJAX crawling scheme in 2015, and modern JavaScript websites no longer need to use hashbang URLs for this purpose.
Today, if different content needs to exist as separate indexable pages, I’d much rather see it available through conventional URLs such as:
https://example.com/services/location-a
That gives users and search engines a distinct URL for the content without relying on a fragment to represent a different page.
Are hashbang URLs bad for SEO?
Hashbang URLs aren’t automatically an SEO problem simply because they contain #!. The bigger issue is using URL fragments to represent content that you want search engines to treat as separate pages.
Google’s current guidance is that fragments generally shouldn’t be used to change the content of a page. For JavaScript applications, Google recommends using the History API to create distinct URLs instead.
For example, if these represent genuinely different location pages:
https://example.com/services/#!/location-a
https://example.com/services/#!/location-b
I’d rather see them implemented as crawlable URLs such as:
https://example.com/services/location-a
https://example.com/services/location-b
Each location can then have its own URL, content, title, meta description, canonical signals and internal links without relying on the fragment to distinguish one page from another.
The problem I encountered with hashbang URLs
The site that originally prompted me to write this article used hashbang URLs for more than 30 location pages.
AJAX loaded different location content for users, but the underlying SEO elements still related to the parent /services-near-you/ page.
This meant multiple location experiences were effectively sharing the same generic page title, meta description and canonical configuration.
At the time, development resources weren’t available to rebuild the functionality, so I used JavaScript through Google Tag Manager to modify those elements according to the hashbang URL.
It worked as a workaround for that particular site, but I wouldn’t recommend implementing the same solution today. If those locations were being rebuilt now, I’d want each one to have a proper crawlable URL and its SEO elements generated as part of the page itself.
Can Google index URLs with fragments?
A URL fragment is everything that appears after the # in a URL.
For example:
https://example.com/services/#location-a
The fragment is:
#location-a
The important point for SEO is that Google generally doesn’t treat URLs that differ only by their fragment as separate pages that should be independently crawled and indexed.
Google’s current JavaScript SEO guidance specifically recommends using the History API instead of fragments when you want different content to have different URLs.
So I wouldn’t build an SEO strategy around URLs such as:
https://example.com/services/#!/location-a
https://example.com/services/#!/location-b
and expect each fragment to behave like a conventional, independently indexable landing page.
If the content deserves to rank separately, give it a proper URL:
https://example.com/services/location-a
https://example.com/services/location-b
This also makes other SEO elements much easier to manage. Each page can have its own title, meta description, canonical URL, internal links and structured data without relying on JavaScript to change them after the page loads.
What should you do if your website still uses hashbang URLs?
If you discover hashbang URLs on an existing website, I wouldn’t immediately remove them just because the implementation is old.
First establish what they’re actually doing.
If the fragments simply control interface behaviour, such as switching tabs or jumping to a particular section of the same page, they may not represent an SEO problem at all.
The bigger concern is when different hashbang URLs load substantially different content that you expect to appear independently in search.
In that situation, I’d investigate:
- whether the content currently receives organic search traffic
- which underlying URLs Google has actually indexed
- how internal links point to the content
- what title, canonical and other page-level signals Google receives
- whether each piece of content genuinely deserves its own indexable URL
If the content should exist as separate search landing pages, I’d look at migrating it to conventional crawlable URLs rather than trying to make the old hashbang architecture more SEO-friendly.
How to replace hashbang URLs
If hashbang URLs are being used for content that deserves to exist as separate pages, I’d normally look at replacing them with conventional crawlable URLs.
For example:
https://example.com/services/#!/location-a
could become:
https://example.com/services/location-a
The new page should contain the content and SEO elements that previously depended on the hashbang state, including its own page title, headings, canonical URL and relevant internal links.
Don’t treat this as a simple URL tidy-up, though. Before changing anything, establish which hashbang content currently receives traffic, attracts links or has visibility in search.
You can then map the old experience to the most appropriate new URL and update internal links so users and search engines reach the new version directly.
Where technically possible, users reaching an old hashbang URL should also be taken to the corresponding replacement page. Fragment-based URLs can make conventional server-side redirects more complicated because the fragment isn’t sent to the server, so the migration method may depend on how the existing application works.
The important objective is that you end up with one stable, crawlable URL for each piece of content you genuinely want indexed.
Should you use hashbang URLs today?
For a new website, I wouldn’t use hashbang URLs to create pages that need to rank independently in search.
Fragments still have perfectly legitimate uses, such as linking users to a particular section of a page or controlling interface behaviour. The problem comes when they’re being used as a substitute for proper URLs for content you expect search engines to discover and index separately.
If I encountered the same location-page problem that originally prompted this article today, I wouldn’t reach for Google Tag Manager to rewrite the metadata. I’d fix the underlying URL architecture and give each location a proper crawlable page.
The old GTM solution was useful for getting around a specific technical limitation at the time. The better long-term solution is to remove that limitation.
If you’re dealing with an older website where JavaScript, AJAX or unusual URL structures are creating indexing problems, that’s the sort of issue I investigate as part of my technical SEO and website optimisation consultancy.
categories
- Analytics Insights
- Crawl Rate Insights
- Ecommerce SEO Insights
- International SEO Insights
- Keyword Research Insights
- Local SEO Insights
- Migrations Insights
- News Insights
- On Page SEO Insights
- Performance Analysis Insights
- SEO Audits Insights
- Site Speed Insights
- Structured Data Insights
- Tag Manager Insights
- Wordpress SEO Insights
latest posts
How To: Track GA4 AI Assistant Traffic, Including Historical Data
A Rough Guide To: LLMS.txt - What It Is & How To Create One
How To: Build SEO Content Hubs for Topical Authority
Case Study: Do Keywords in URLs Help SEO Rankings?
How To: Track Google Business Profile Traffic in GA4
get in touch
If you need some expert website optimisation and configuration, want to find out more, or even just have a question, fill in the form below as I will always be happy to help