Another option is to make a website that works without JavaScript. Only dynamically fetch pages when JavaScript is enabled. Progressive enhancement rocks.<p>Visiting <a href="http://monocle.io/posts/how-yield-will-transform-node" rel="nofollow">http://monocle.io/posts/how-yield-will-transform-node</a> without JavaScript support yields a blank page.<p>All page titles are <title>Monocle</title> which isn't very descriptive and the meta description is the same for every page. Only with escaped_fragment can a user see descriptive page titles. For JavaScript users all pages are titled "Monocle".<p>There are no unique content articles to rank nr. 1 for. The articles are all found on other sites. I don't really see Monocle rank 2 a lot (a quick glance). Those are reserved for other aggregating sites.<p>The Google guidelines say:<p><pre><code> Make pages primarily for users, not for search engines.
"Does this help my users? Would I do this if search
engines didn't exist?"
</code></pre>
I'd extend that to JavaScript apps. Why make escaped_fragment especially for search engines, and then forget to offer this functionality for human users too?
For an article that aims to <i>"put misconceptions to rest"</i>, it's pretty damn short.<p>My companies do website/CMS services for small businesses–so SEO is WAY more important to us than an app or a content aggregator like Monocle. If our clients suspect SEO sucks for our product they will leave. Conversely, if our product has a reputation for good SEO, it can drive a lot of business to us.<p>Also, Monocle.io isn't setting the title tag for any of their URLs, so that's a pretty poor example to use wrt SEO.<p>I'd like to see a real, in-depth article that discusses the following:<p>- At this point, should I use hash-fragments or pushState?<p>- Which front-end JS framework (backbone, ember, angular, etc) has the best support for SEO features out of the box?<p>- Is Rails 4 + Turbolinks SEO-friendly?<p>- I'd love to see some kind of experiment/example showing that a JS/hash_fragment based site can actually rank well when competing against basic HTML sites. I know that SEO comes down to content and links (more or less) so experiments like that are hard/impossible. I just used to do a lot of SEO for Flash sites back in they day. In the end, <i>you could only do so much</i> and I worry that doing SEO for JS sites is similar.<p>Just because Google provides the hash-fragment feature doesn't mean they don't give such sites less weight when ranking.
Monocle.io is not getting indexed correctly.<p>see:<p><a href="https://www.google.com/search?q=%22Node+has+had+great+success+because+of+how+simple+npm+is+to+use%22" rel="nofollow">https://www.google.com/search?q=%22Node+has+had+great+succes...</a><p>Notice how the monocle.io link is totally useless. Overtime, this will get you killed by Google as they realize your domain is returning useless results.
So he starts with a JavaScript only application, then retrofits in a progressive enhancement layer in a Google-specified query string parameter.<p>He could just as easily done the core experience first with HTML, got a URL structure that is friendlier and RESTful, and then enhanced it with the JavaScript enhancement he needs to turn it into a perception of a one page website.<p>The bonus of doing it this way is clean URLs for each piece of indexable content.<p>Because, really, what's the advantage of <a href="http://example.com/?_escaped_fragment_=about-us" rel="nofollow">http://example.com/?_escaped_fragment_=about-us</a> over <a href="http://example.com/about-us" rel="nofollow">http://example.com/about-us</a> ?
i will save you a lot of pain: just don't do it. the __escaped_fragment__ is the most idiotic recommendation google has ever given. basically you have to render two views, the user JS view and a server side rendered basic HTML __escaped_fragment__ view. oh yeah, the __escaped_fragment__ view will never be visited by your users and not by yourself - just by googlebot.<p>and now guess: what view will be less maintained, not up to date and regularly broken?<p>why? when there is no direct feedback, there is no direct feedback.<p>if you want to do SEO and as well go down the "but it's faster with JS" road just do "progressive enhancement" and history.pushState. the __escaped_fragment__ spec is a leftover from the ajaxy web2.0 times, and even then it was a bad idea.
I find it a little odd that this article focuses on the hash fragment approach and only mentions the HTML5 pushState in passing, and how to avoid it. There are a few scenarios where the hash fragment is more useful (states that don't map well to URLs), but pushState has the huge benefit of looking natural AND working in non-JS browsers in general.<p>I think it would be good to mention Sinatra in the title.
People should keep in mind that you do not always have the benefit of green field development; sometimes you have a project already written that does not have much of server-side component, and has no budget or time left for adding real pages/do graceful degradation (much less progressive enhancement.) In these cases, using a spider is pretty much your only choice. Some notes/recommendations:<p>- I'd recommend PhantomJS (there are some other packages built on top of it, but for my custom needs, using the original was better)<p>- If you spider a whole site, especially if it's somewhat complicated, log what you're spidering and see if and where it hangs. I started getting some PhantomJS hangs after ~100 URLs. In this case, it can be a good idea to do multiple spidering runs using different entry points (I use command line options to exclude certain URL patterns I know were spidered during previous runs)<p>- If you're spidering sites using script loaders (like require.js), pay careful attention to console errors; if you notice things aren't loading, you may have to tweak your load timeout to compensate. Using a "gnomon" (indicator) CSS selector is very helpful here.<p>- Add a link back to your static version for no-JS people in case Google/Bing serves up the static version. This only seemed to be problem shortly after spidering, but it's worth doing regardless (later, search engines seemed to start serving the real version)<p>- For those wondering how to keep the static version up-to-date, use a cron job, then cp/rsync/whatever your latest version to your "static" directory.<p>One thing I'd like to add is that I wish PhantomJS would support more things that node.js does (since some of its API is modeled after it), particularly many synchronous versions of functions. That aside, it's an incredibly useful piece of software.
I made a web service that will do javascript SEO for you. Check it out at BromBone.com.<p>We render your entire page for you a save it has html on a CDN. Then you can just do the simple routing described in this article, but send Google the page from our CDN instead. That way Google sees the exact same thing as your users, but you don't have to code it again.
Does it matter that the JS-constructed HTML does not look anything like the spider-friendly version?<p>We're about to deploy an AngularJS application that is using PhantomJS to generate the spider-friendly content on the server. I'd much prefer to do this simpler method if it works just as well.
For AngularJS apps, you are welcome to try (and improve!) AngularSEO <a href="https://github.com/steeve/angular-seo" rel="nofollow">https://github.com/steeve/angular-seo</a> (based on PhantomJS)
So, basically, the article says that in order to have good SEO with full js apps, you must also expose a non js app?<p>Like, you have to implement 2 sets of templates - one "classic", html only, and one for js?
<a href="https://www.cityblis.com/" rel="nofollow">https://www.cityblis.com/</a> I implemented the <noscript> solution which actually shows the same content (without dynamic positioning) to the users and allows them to go to non-javascript versions of the pages. With JS on I serve dynamically positioned content and with scrolls.<p>I also have an implementation for the search, but it's not pushed yet. It doesn't paint the first page, but only provides pagination for the users without JS.<p>What do you think of this kind of a solution?
Personally i only serve client-side rendered content to browsers that are in my whitelist, everything else gets the server rendered content.<p><a href="http://chadscira.com/" rel="nofollow">http://chadscira.com/</a> (set your user-agent to blank)
I wrote about using the same technique with a headless browser a while ago.<p><a href="http://backbonetutorials.com/seo-for-single-page-apps/" rel="nofollow">http://backbonetutorials.com/seo-for-single-page-apps/</a><p>Works nicely...