seo for developers
DESCRIPTION
Slides from my talk atTRANSCRIPT
Date:
Author:
February 29, 2012
Chris Le (@djchrisle)
SEO For DevelopersSELECT * WHERE clue > 0;
1
realv
$ whoami{ name: “Chris Le”, twitter: “@DjChrisLe”,
occupation: [ “Internal app developer”, “Project management”, “Technical SEO support” ]}
If you build it, they will come is a lie 3
Date:
Author:
February 29, 2012
Chris Le (@djchrisle)
SEO For DevelopersHow SEO changed the way I develop
4
realv
5
@djchrisle 6
@djchrisle 7
# header.html.erb<h1> </h1>....
# acme.cssh1 { background-‐image: ‘/img/acme_logo.png’; background-‐repeat: no-‐repeat;}
@djchrisle 8
# investments.html.erb<a href=”#watchlist”><div id=”container”></div><script> $(“#watchlist”).click (function() {
// => sets loadThis to “watchlist” var loadThis = $.param.fragment($.param.querystring); $(“#container”).load(“/content?get=” + loadThis); }</script>
# content_controller.rbclass ContentController < ActionController::Base respond_to :html
def index @content = Content.find_by_name(params[:get] respond_with(@content) endend
@djchrisle 9
http://www.acme.com/investments#positionshttp://www.acme.com/investments#watchlisthttp://www.acme.com/investments#menu1http://www.acme.com/investments#menu2
@djchrisle
Best Practices
10
• Modularize & reuse code– DRY principals (Don’t Repeat Yourself)
• Abstract template and view from logic– Independently change stuff - no problems
• Use async JS loading to reduce load– Lower server costs– Fast load time (aka: “site speed”)
@djchrisle 11
http://www.domain.com/about-‐us/blog/posthttp://www.domain.com/blog/post
Q: What is SEO?
12
A: Help the RIGHT customers find YOU.
About us
13
@djchrisle 14
@djchrisle 15
@djchrisle 16
@djchrisle 17
require 'anemone'
Anemone.crawl("http://www.example.com/") do |anemone| anemone.on_every_page do |page| puts page.url endend
Bank.account << Profit!
@djchrisle 18
nsfw 19
@djchrisle
Title tags
20
21
????
@djchrisle 22
# header.html.erb<title><%= @company.name %></title>
@djchrisle 23
# header.html.erb<title><%= @company.name %> <%= @page.title_tag %></title>
@djchrisle 24
# header.html.erb<title><%= @company.name %> <%= @page.title_tag %></title>
# schema.rbcreate_table “Page” t.string “title_tag” ...end
# page.rbClass Page < ActiveRecord::Base belongs_to :category def title_tag title_tag.defined? ? super() : self.category.name endend
@djchrisle 25
puts Page.find(1).inspect
{ title_tag: “Experienced Ruby Programmers in Philladelphia”, content: “...”}
26
My Company | Experienced Ruby Programmers in Philadelphia
Title matches keyword+ is what user is looking for
@djchrisle
<h1> tags
27
@djchrisle 28
# post/index.html.erb<h1><%= @post.title %></h1>
@djchrisle 29
@djchrisle 30
@djchrisle 31
# my_page.html.erb<h1> </h1>....
# acme.cssh1 { background-‐image: ‘/img/acme_logo.png’; background-‐repeat: no-‐repeat;}
@djchrisle 32
# my_page.html.erb<h1> </h1>....
# acme.cssh1 { background-‐image: ‘/img/acme_logo.png’; background-‐repeat: no-‐repeat;}
This page is about “Non-breaking space?”
@djchrisle 33
# my_page.html.erb<div class=”logo”></div><h1> Sensible Investment Strategies </h1>....
# acme.css.logo { background-‐image: ‘/img/acme_logo.png’; background-‐repeat: no-‐repeat;}
Better use of H1
@djchrisle
URLs &Hash fragments
34
@djchrisle 35
http://www.acme.com/investments#positionshttp://www.acme.com/investments#watchlisthttp://www.acme.com/investments#menu1http://www.acme.com/investments#menu2
@djchrisle 36
http://www.acme.com/investments#positionshttp://www.acme.com/investments#watchlisthttp://www.acme.com/investments#menu1http://www.acme.com/investments#menu2
www.acme.com/investmentsAcme Inc | Financial Portfolio Managers
4 pages .. 1 listing :(
37
# investments.html.erb
<a href=”#watchlist”>
<div id=”container”></div>
<script> $(“#watchlist”).click (function() {
// => sets loadThis to “watchlist” var loadThis = $.param.fragment($.param.querystring); $(“#container”).load(“/content?get=” + loadThis); }</script>
Uncrawlable URL
38
# investments.html.erb
<a href=”/investments/watchlist”>
<div id=”container”></div>
<script> $(“#watchlist”).click (function() { $(“#container”).load($.param.querystring); }</script>
Crawlable URL
@djchrisle 39
# routes.rbresources :investmentsmatch “content/:section” => “content#show”
# content_controller.rbclass ContentController < ActionController::Base respond_to :html
def show @content = Content.find_by_name(params[:section]) respond_with(@content) endend
@djchrisle 40
http://www.acme.com/investments/positionshttp://www.acme.com/investments/watchlisthttp://www.acme.com/investments/menu1http://www.acme.com/investments/menu2
www.acme.com/investments/positionsAcme Inc | Financial Portfolio Managers
4 pages .. 4 listings :)
@djchrisle
301 / 302 redirect
41
@djchrisle 42
http://www.domain.com/about-‐us/blog/posthttp://www.domain.com/blog/post
@djchrisle 43
# content_controller.rbclass ContentController < ActionController::Base respond_to :html
def show redirect_to :post_path # @content = Content.find_by_id(params[:id]) # respond_with(@content) endend
@djchrisle 44
# content_controller.rbclass ContentController < ActionController::Base respond_to :html
def show redirect_to :post_path # @content = Content.find_by_id(params[:id]) # respond_with(@content) endend
Defaults as 302 response
@djchrisle
301 vs 302 redirect
45
• RFC 2616, Section 10.3.3– 302 Found: The requested resource resides
temporarily under a different URI
• RFC 2616, Section 10.3.2–301 Moved Permanently: The requested resource has
been assigned a new permanent URI and any future references to this resource SHOULD use one of the returned URIs
46
47
302 = nothing
48
301 = change
49
404 = delist
@djchrisle 50
# content_controller.rbclass ContentController < ActionController::Base respond_to :html
def show redirect_to :post_path, :status => 301 # @content = Content.find_by_id(params[:id]) # respond_with(@content) endend
@djchrisle 51
# content_controller.rbclass ContentController < ActionController::Base respond_to :html
def show redirect_to :post_path, :status => 301 # @content = Content.find_by_id(params[:id]) # respond_with(@content) endend
52
# routes.rb
match “/about-‐us/blog/:post_title” => redirect(“/blog/#{params[:post_title]}”)
If you build it, they will come is a lie 53
@djchrisle
Every great idea deserves the
chance to be found
54
Date:
Author:
February 29, 2012
Chris Le (@djchrisle)
SEO For DevelopersHow SEO changed the way I develop
55
realv
@djchrisle
Q&A
56
57
2006-2007
58