Is it that easy? SEO and AngularJS

Is it that easy? SEO and AngularJS

Use PushState

The current (2014) way to do this is using the JavaScript pushState method.

PushState changes the URL in the top browser bar without reloading the page. Say you have a page containing tabs. The tabs hide and show content, and the content is inserted dynamically, either using AJAX or by simply setting display:none and display:block to hide and show the correct tab content.

When the tabs are clicked, use pushState to update the url in the address bar. When the page is rendered, use the value in the address bar to determine which tab to show. Angular routing will do this for you automatically.

Search Engines can read and execute JavaScript

Google has been able to parse JavaScript for some time now, it’s why they originally developed Chrome, to act as a full featured headless browser for the Google spider. If clicking a link triggers a pushState call, the new URL can be indexed. There’s nothing more to do.

Search Engine Support for PushState URLs

PushState is currently supported by Google and Bing.

Don’t use HashBangs #!

Hashbang urls were an ugly stopgap requiring the developer to provide a pre-rendered version of the site at a special location. They still work, but you don’t need to use them.


Here’s Matt Cutts responding to Paul Irish’s question about PushState for SEO:

Here is Google announcing full JavaScript support for the spider:

The upshot is that Google supports PushState and will index PushState URLs.

See also Google webmaster tools’ fetch as Googlebot. You will see your JavaScript (including Angular) is executed.


Here is Bing’s announcement of support for pretty PushState URLs dated March 2013:

Don’t mix your technologies

Hashbang URLs look like this:!path/to/resource

This would be paired with a metatag like this:

<meta name="fragment" content="!">

Google will not index them in this form, but will instead pull a static version of the site from the _escaped_fragments_ URL and index that.

Pushstate URLs look like any ordinary URL:

The difference is that Angular handles them for you by intercepting the change to document.location dealing with it in JavaScript.

If you want to use PushState URLs (and you probably do) take out all the old hash style URLs and metatags and simply enable HTML5 mode in your config block.

Testing your site

Google Webmaster tools now contains a tool which will allow you to fetch a URL as google, and render JavaScript as Google renders it.

Generating pushstate URLs in Angular

To generate real URLs in Angular, rather than # prefixed ones, set HTML5 mode on your $locationProvider object.


Server Side

Since you are using real URLs, you will need to ensure the same template gets shipped by your server for all valid URLs. How you do this will vary depending on your server architecture.


Your app may use unusual forms of navigation, for example hover or scroll. To ensure Google is able to drive your app, I would probably suggest creating a sitemap, a simple list of all the urls your app responds to. You can place this at the default location (/sitemap or /sitemap.xml), or tell Google about it using webmaster tools.

It’s a good idea to have a sitemap anyway.

Browser support

Pushstate works in IE10. In older browsers, Angular will automatically fall back to hash style URLs

A demo page

The following content is rendered using a pushstate URL:

As can be verified, at this link, the content is indexed and is appearing in Google.