Old AJAX Crawling Scheme: Why escaped_fragment URLs Must Go
- May 21, 2026
- Indexation, JavaScript

This check fires when a site still uses the AJAX crawling URL scheme — hashbang URLs like example.com/#!/products paired with a server that answers ?_escaped_fragment_= requests with pre-rendered snapshots. Google deprecated this scheme in 2015 and stopped supporting it entirely around 2018, switching to rendering JavaScript directly. Keeping it means Googlebot crawls your ugly hashbang and escaped-fragment URLs instead of clean ones, splits signals across duplicate address forms, and depends on a snapshot pipeline Google no longer requests.
This check is about the URLs and the request handling. The head-level opt-in that used to switch this on — <meta name="fragment" content="!"> — has its own check: Old AJAX Crawling Meta Fragment. Fix them together; they're two ends of the same obsolete rope.
How the scheme worked and why it's a liability
Hashbang (#!) URLs let single-page apps put state after the fragment while signaling crawlers that the fragment was meaningful. Google's rule: when it saw #! in a URL, it rewrote the request to ?_escaped_fragment_= and fetched a server-rendered snapshot to index. Your server had to detect that parameter and return flat HTML.
Google now renders JS itself, so it never sends _escaped_fragment_ requests anymore. What's left is a mess of non-canonical URLs. Here's the failing pattern — a hashbang link and the escaped-fragment form Google used to request:
<!-- Hashbang links still in the markup -->
<a href="https://example.com/#!/products/blue-widget">Blue Widget</a>
<!-- The snapshot URL Google used to fetch (now unused) -->
https://example.com/?_escaped_fragment_=/products/blue-widget
<!-- These fragment forms fragment your signals across
multiple address shapes for the same content -->Fragments after # aren't even sent to the server on a normal request, so a modern crawler landing on /#!/products/blue-widget may just see the app shell. Meanwhile the escaped-fragment URLs, if still linked or indexed, compete with your real URLs.
The fix: clean URLs plus the History API
<!-- Real, crawlable path URLs -->
<a href="https://example.com/products/blue-widget">Blue Widget</a>
// Client routing via the History API, not hashbangs
history.pushState({}, '', '/products/blue-widget');
<!-- Server renders this path to full HTML (SSR/SSG) -->Swap hashbang routing for the History API so every view has a real path URL, then make the server return complete HTML for those paths. Redirect any lingering hashbang or escaped-fragment URLs to their clean equivalents so you don't strand indexed versions.
URL forms: retire vs. keep
| URL form | Example | Action |
|---|---|---|
| Hashbang | /#!/products/blue-widget | Retire — migrate to path URLs |
| Escaped fragment | /?_escaped_fragment_=/products/blue-widget | Retire — redirect to clean URL |
| Clean path (History API) | /products/blue-widget | Keep — this is the target |
| Snapshot endpoint | Server handler for _escaped_fragment_ | Decommission after redirects |
How to detect it
- Screaming Frog. Crawl and inspect the URL tab for addresses containing
#!or_escaped_fragment_. Frog's Internal → HTML list plus a filter on those strings surfaces every offender. Also check Response Codes for escaped-fragment URLs that still return 200 — those are live snapshots you need to redirect. - View Source. Ctrl+U and Ctrl+F for
#!inhrefattributes. If your navigation is built on hashbang links, they'll be all over the source. Manually try appending?_escaped_fragment_=to a URL — if the server returns a rendered snapshot, the old handler is still active. - Google Search Console. Search the Page indexing report and coverage data for indexed URLs containing
_escaped_fragment_or#!. Use URL Inspection on a clean path URL to confirm it renders fully — if Google can read the path version directly, you're clear to retire the scheme.
How to fix it
- Confirm clean URLs render. Make sure each path URL returns complete HTML to a crawler before you cut over. Use GSC's rendered view to verify.
- Migrate routing to the History API so links use real paths instead of hashbangs.
- 301-redirect hashbang and
_escaped_fragment_URLs to their clean equivalents. Hashbang redirects usually need a small client-side script since the fragment never reaches the server. - Serve crawlable HTML via server-side rendering or static generation. If a full refactor isn't immediate, prerendering bridges the gap.
- Decommission the snapshot endpoint and remove the meta fragment tag once redirects are in place.
FAQ
Is Google still fetching my escaped-fragment URLs?
No. Google stopped requesting _escaped_fragment_ versions after retiring the scheme. Any that remain indexed are legacy artifacts you should redirect, not content Google is actively snapshotting.
What's wrong with hashbang URLs specifically?
The part after # isn't sent to the server, so a crawler that doesn't fully execute your JS may only see the app shell. Clean path URLs are unambiguous and render server-side, which every crawler can read.
How do I redirect a hashbang URL if the fragment never reaches the server?
You handle it client-side: a small script reads location.hash, maps #!/products/blue-widget to /products/blue-widget, and issues a redirect. Server 301s handle the escaped-fragment forms since those are sent to the server.
How does this differ from the meta fragment check?
This check is the URL scheme — the #! and _escaped_fragment_ addresses and handling. The meta fragment check is the head tag that opted a page into it. Clean up both.
Will AI crawlers read a hashbang site?
Usually not well. Many AI crawlers execute minimal JavaScript and can't resolve fragment-based routing at all, so hashbang sites often render as empty shells to them. Migrating to server-rendered path URLs fixes visibility for Google and AI bots alike — see SSR vs CSR.
Claude Vincent is a technical SEO consultant focused on crawlability, rendering, and AI-search visibility. He writes the field guides and case studies at SEO ProCheck, with a bias toward the durable, unglamorous work that decides whether search engines and AI answer engines can actually read and cite a site.
About SEO ProCheck
Technical SEO consulting and GEO strategy with 20 years of enterprise experience. Case studies, resources, and tools for search and AI visibility.
Work With Me
Technical SEO audits, GEO strategy, site migrations, and international SEO. Hourly consulting for teams who need hands-on support, not just reports.







