denver emberjs-sept-2015

56
Building a Like-able (and Searchable) Ember App Ember Denver Meetup Sept 30, 2015

Upload: ron-white

Post on 12-Jan-2017

144 views

Category:

Technology


0 download

TRANSCRIPT

Building a Like-able (and Searchable)

Ember AppEmber Denver Meetup Sept 30, 2015

Ron White! ronco " @ronco1337

I’m No SEO Expert

#Sh*tMySEOExpertSays

“Defer loading all JavaScript until after the page has loaded.”

I’m No SEO Expert

Techniques for Making Ember Searchable

I’m No SEO Expert

Lots of Great Ember Apps

Delivery Company Blog

How do you drive traffic to these sites?

Time to Make a Metaphorical Deal

With The Devil

Time to Make a Deal With The Devil

Demo

http://peblog-3000.herokuapp.com/?index_key=dc3041e

Bots have their own language

• Content is King

• Data is pulled directly from your markup

• Structure should be logical and useful to users

• Avoid Repeated Content (Canonicalization)

• Links to/from Your Site Drive Importance

• Easy to Implement, Lifetime to Master

Source: https://support.google.com/webmasters/answer/40349?hl=en

• Facebook Open Graph

• Dedicated Meta Tag Markup in Head

• Requires Canonicalization

• Shared Open Spec

1 <meta property="og:url" 2 content="http://www.nytimes.com/.../mars-life-liquid-water.html"> 3 <meta property="og:type" content="article"> 4 <meta property="og:title" 5 content="NASA Confirms Signs of Water Flowing on Mars, Possible 6 Niches for Life">

• Twitter Cards

• Dedicated Meta Tag Markup in Head

• Will Read Open Graph Also

1 <meta name="twitter:card" value="summary"> 2 <meta name="twitter:site" value="@nytimes"> 3 <meta property="twitter:url" 4 content=“http://.../mars-life-liquid-water.html”> 5 <meta property=“twitter:title" 6 content="NASA Confirms Signs of Water Flowing on Mars, 7 Possible Niches for Life">

schema.org

• Used by Pinterest & Google Structured Data

Let’s Mark-up Our Blog

./app/index.html 1 <meta property="og:title" 2 content="The Latest Happenings At New New York's Greatest 3 Delivery Service"> 4 <meta property="og:site_name" content="Planet Express Blog"/> 5 <meta property="og:description" 6 content="The Employees of Planet Express, New New York's 7 Greatest Delivery Service, have a lot to say. Hear 8 all their latest musings on the Planet Express Blog." 9 /> 10 <meta property="og:type" content="website" /> 11 <meta property="og:image" content="/images/pe-logo.png" />

Demo

http://peblog-3000.herokuapp.com/?index_key=e4df1d5

Not Very Practical

$ ember install ember-cli-meta-tags

./app/routes/application.js 1 import Ember from 'ember'; 2 3 export default Ember.Route.extend({ 4 model() { 5 return this.get('store').findAll('author'); 6 }, 7 8 headTags() { 9 return [ 10 { 11 tagId: 'og:title', 12 type: 'meta', 13 attrs: { 14 property: 'og:title', 15 content: "The Latest Happenings At New New York's Greatest 16 Delivery Service" 17 } 18 }, 19 { 20 tagId: 'og:site_name', 21 type: 'meta', 22 attrs: { 23 property: 'og:site_name', 24 content: "Planet Express Blog", 25 } 26 }, 27 // ... 28 ]; 29 } 30 }); 31

./app/routes/application.js

8 headTags() { 9 return [ 10 { 11 tagId: 'og:title', 12 type: 'meta', 13 attrs: { 14 property: 'og:title', 15 content: "The Latest Happenings At New New York's Greatest 16 Delivery Service" 17 } 18 }, 27 // ... 28 ];

./app/routes/author.js 1 headTags() { 2 let model = this.modelFor(this.routeName); 3 return [ 4 { 5 tagId: 'og:title', 6 type: 'meta', 7 attrs: { 8 property: 'og:title', 9 content: model.get('name') 10 } 11 }, 12 // ... 13 ]; 14 }

./app/routes/post.js

1 headTags() { 2 let model = this.modelFor(this.routeName); 3 return [ 4 { 5 tagId: 'og:title', 6 type: 'meta', 7 attrs: { 8 property: 'og:title', 9 content: model.get('title') 10 } 11 },

./app/routes/author/post.js 1 headTags() { 2 let model = this.modelFor(this.routeName); 3 let queryParams = { 4 index_key: this.controllerFor('application').get('indexKey') 5 }; 6 let router = this.get('router'); 7 let path = this.get('router').generate.apply(router, [ 8 'post', model, { 9 queryParams: queryParams 10 } 11 ]); 12 let cannonicalUrl = `${window.location.origin}${path}`; 13 return [ 14 // ... 15 { 16 tagId: 'og:url', 17 type: 'meta', 18 attrs: { 19 property: 'og:url', 20 content: cannonicalUrl, 21 } 22 }, 23 ]; 24 }

./app/routes/author/post.js

2 let model = this.modelFor(this.routeName); 3 let queryParams = { 4 index_key: this.controllerFor('application').get('indexKey') 5 }; 6 let router = this.get('router'); 7 let path = this.get('router').generate.apply(router, [ 8 'post', model, { 9 queryParams: queryParams 10 } 11 ]); 12 let cannonicalUrl = `${window.location.origin}${path}`;

./app/routes/author/post.js 1 headTags() { 2 let model = this.modelFor(this.routeName); 3 let queryParams = { 4 index_key: this.controllerFor('application').get('indexKey') 5 }; 6 let router = this.get('router'); 7 let path = this.get('router').generate.apply(router, [ 8 'post', model, { 9 queryParams: queryParams 10 } 11 ]); 12 let cannonicalUrl = `${window.location.origin}${path}`; 13 return [ 14 // ... 15 { 16 tagId: 'og:url', 17 type: 'meta', 18 attrs: { 19 property: 'og:url', 20 content: cannonicalUrl, 21 } 22 }, 23 ]; 24 }

./app/routes/author/post.js

15 { 16 tagId: 'og:url', 17 type: 'meta', 18 attrs: { 19 property: 'og:url', 20 content: cannonicalUrl, 21 } 22 },

Demo

http://peblog-3000.herokuapp.com/?index_key=ddcec57

Bots don’t speak Javascript

$ npm install prerender-node

<server>/index.js

1 app.use(require(‘prerender-node') 2 .set('prerenderToken', process.env.PRERENDER_TOKEN));

./app/index.html

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

Ajax Crawling

http://www.example.org/#mypage

http://www.example.org/?_escaped_fragment_=mypage

http://www.example.org/mypage

http://www.example.org/mypage?_escaped_fragment_=

Demo

http://peblog-3000.herokuapp.com/?index_key=da65289

$ ember install ember-cli-fastboot

ember-cli-fastboot

• Ember Core Team Provided Pre-rendering

• Deferred Injection of Scripts

• Available as Node Middleware

• Extremely Alpha

• Bugs & Incomplete

Demo

• https://support.google.com/webmasters/answer/40349?hl=en

• http://static.googleusercontent.com/media/www.google.com/en//webmasters/docs/search-engine-optimization-starter-guide.pdf

• https://developers.google.com/webmasters/ajax-crawling/docs/getting-started?hl=en

• https://dev.twitter.com/cards/overview

• http://ogp.me/

• https://developers.facebook.com/tools/debug/