Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h1>Let's get definitive about AngularJS and SEO</h1> <p>Google, Yahoo, Bing, and other search engines crawl the web in traditional ways using traditional crawlers. They run <em>robots</em> that crawl the HTML on web pages, collecting information along the way. They keep interesting words and look for other links to other pages (these links, the amount of them and the number of them come into play with SEO). </p> <h2>So why don't search engines deal with javascript sites?</h2> <p>The answer has to do with the fact that the search engine robots work through headless browsers and they most often do <em>not</em> have a javascript rendering engine to render the javascript of a page. This works for most pages as most static pages don't care about JavaScript rendering their page, as their content is already available.</p> <h2>What can be done about it?</h2> <p>Luckily, crawlers of the larger sites have started to implement a mechanism that allows us to make our JavaScript sites crawlable, but it <strong>requires us to implement a change to our site</strong>.</p> <p>If we change our <code>hashPrefix</code> to be <code>#!</code> instead of simply <code>#</code>, then modern search engines will change the request to use <code>_escaped_fragment_</code> instead of <code>#!</code>. (With HTML5 mode, i.e. where we have links without the hash prefix, we can implement this same feature by looking at the <code>User Agent</code> header in our backend).</p> <p>That is to say, instead of a request from a normal browser that looks like:</p> <p><code>http://www.ng-newsletter.com/#!/signup/page</code></p> <p>A search engine will search the page with:</p> <p><code>http://www.ng-newsletter.com/?_escaped_fragment_=/signup/page</code></p> <p>We can set the hash prefix of our Angular apps using a built-in method from <code>ngRoute</code>:</p> <pre><code>angular.module('myApp', []) .config(['$location', function($location) { $location.hashPrefix('!'); }]); </code></pre> <p>And, if we're using <code>html5Mode</code>, we will need to implement this using the meta tag:</p> <pre><code>&lt;meta name="fragment" content="!"&gt; </code></pre> <p>Reminder, we can set the <code>html5Mode()</code> with the <code>$location</code> service:</p> <pre><code>angular.module('myApp', []) .config(['$location', function($location) { $location.html5Mode(true); }]); </code></pre> <h2>Handling the search engine</h2> <p>We have a lot of opportunities to determine how we'll deal with actually delivering content to search engines as static HTML. We can host a backend ourselves, we can use a service to host a back-end for us, we can use a proxy to deliver the content, etc. Let's look at a few options:</p> <h3>Self-hosted</h3> <p>We can write a service to handle dealing with crawling our own site using a headless browser, like phantomjs or zombiejs, taking a snapshot of the page with rendered data and storing it as HTML. Whenever we see the query string <code>?_escaped_fragment_</code> in a search request, we can deliver the static HTML snapshot we took of the page instead of the pre-rendered page through only JS. This requires us to have a backend that delivers our pages with conditional logic in the middle. We can use something like <a href="https://prerender.io/">prerender.io's</a> backend as a starting point to run this ourselves. Of course, we still need to handle the proxying and the snippet handling, but it's a good start.</p> <h3>With a paid service</h3> <p>The easiest and the fastest way to get content into search engine is to use a service <a href="http://www.brombone.com/">Brombone</a>, <a href="http://getseojs.com/">seo.js</a>, <a href="http://www.seo4ajax.com/">seo4ajax</a>, and <a href="https://prerender.io/">prerender.io</a> are good examples of these that will host the above content rendering for you. This is a good option for the times when we don't want to deal with running a server/proxy. Also, it's usually super quick.</p> <p>For more information about Angular and SEO, we wrote an extensive tutorial on it at <a href="http://www.ng-newsletter.com/posts/serious-angular-seo.html">http://www.ng-newsletter.com/posts/serious-angular-seo.html</a> <strong>and</strong> we detailed it even more in our book <strong>ng-book: The Complete Book on AngularJS</strong>. Check it out at <a href="https://www.ng-book.com/">ng-book.com</a>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload