prerender_rails 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/README.md +45 -23
- data/Rakefile +11 -0
- data/lib/prerender_rails.rb +58 -21
- data/prerender_rails.gemspec +5 -5
- data/test/lib/prerender_rails.rb +97 -0
- data/test/test_helper.rb +4 -0
- metadata +37 -5
- data/lib/rack/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e710c94d4517957a7198a878b74edb3d2ce599a
|
4
|
+
data.tar.gz: 3d61079a206b75b6ebf47d2acd64ed1774fa1b25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2f1fd70277c97905a06b2e674ca4e882aea82700c8abdc65eb65e6b4f2a016392f1bb97482bcd8e7fc87269f26ef51ced69b8cdfb2e937abff8b85c209c9abe
|
7
|
+
data.tar.gz: d5f453676bf4373c2c6634713684ccd938ca1761cea76518ec29aff5b2f3a5ce5567fc8083befa2df2d6afe31dd8ba78c7f6191f1319df06246d548d415373b4
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,46 +1,68 @@
|
|
1
|
-
Prerender Rails
|
1
|
+
Prerender Rails [![Build Status](https://travis-ci.org/collectiveip/prerender_rails.png)](https://travis-ci.org/collectiveip/prerender_rails)
|
2
2
|
===========================
|
3
3
|
|
4
|
-
|
4
|
+
Are you using backbone, angular, emberjs, etc, but you're unsure about the SEO implications?
|
5
5
|
|
6
|
-
|
7
|
-
* Check to make sure the request is from a crawler and we aren't requesting a resource (js, css, etc...)
|
8
|
-
* Make a `GET` request to the [prerender service](https://github.com/collectiveip/prerender) for the page's prerendered HTML
|
9
|
-
* Return that HTML to the crawler
|
10
|
-
|
11
|
-
## Installation
|
6
|
+
Use this gem to install rails middleware that prerenders a javascript-rendered page and returns the HTML to the search engine crawler for SEO.
|
12
7
|
|
13
8
|
Add this line to your application's Gemfile:
|
14
9
|
|
15
10
|
gem 'prerender_rails'
|
16
11
|
|
17
|
-
And
|
12
|
+
And in `config/environment/production.rb`, add this line:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
config.middleware.use Rack::Prerender
|
16
|
+
```
|
18
17
|
|
19
|
-
|
18
|
+
## How it works
|
19
|
+
1. Check to make sure we should show a prerendered page
|
20
|
+
1. Check if the request is from a crawler (agent string)
|
21
|
+
2. Check to make sure we aren't requesting a resource (js, css, etc...)
|
22
|
+
3. (optional) Check to make sure the url is in the whitelist
|
23
|
+
4. (optional) Check to make sure the url isn't in the blacklist
|
24
|
+
2. Make a `GET` request to the [prerender service](https://github.com/collectiveip/prerender)(phantomjs server) for the page's prerendered HTML
|
25
|
+
3. Return that HTML to the crawler
|
20
26
|
|
21
|
-
|
27
|
+
## Customization
|
22
28
|
|
23
|
-
|
29
|
+
### Whitelist
|
24
30
|
|
25
|
-
|
31
|
+
Whitelist a single url path or multiple url paths. If a whitelist is supplied, only url's containing a whitelist path will be prerendered.
|
32
|
+
```ruby
|
33
|
+
config.middleware.use Rack::Prerender, whitelist: '/search/tto'
|
34
|
+
```
|
35
|
+
```ruby
|
36
|
+
config.middleware.use Rack::Prerender, whitelist: ['/search', '/profile']
|
37
|
+
```
|
26
38
|
|
27
|
-
|
39
|
+
### Blacklist
|
28
40
|
|
41
|
+
Blacklist a single url path or multiple url paths. If a blacklist is supplied, all url's will be prerendered except ones containing a blacklist path.
|
29
42
|
```ruby
|
30
|
-
|
43
|
+
config.middleware.use Rack::Prerender, blacklist: '/search/tto'
|
31
44
|
```
|
45
|
+
```ruby
|
46
|
+
config.middleware.use Rack::Prerender, blacklist: ['/search', '/profile']
|
47
|
+
```
|
48
|
+
|
49
|
+
### Using your own prerender service
|
50
|
+
|
51
|
+
If you've deployed the prerender service on your own, set the `PRERENDER_SERVICE_URL` environment variable so that this package points there instead. Otherwise, it will default to the service already deployed at `http://prerender.herokuapp.com`
|
32
52
|
|
33
|
-
|
53
|
+
$ export PRERENDER_SERVICE_URL=<new url>
|
34
54
|
|
35
|
-
|
55
|
+
## Testing
|
36
56
|
|
37
|
-
|
57
|
+
If you want to make sure your pages are rendering correctly:
|
38
58
|
|
39
|
-
1.
|
40
|
-
2.
|
41
|
-
3.
|
42
|
-
4.
|
43
|
-
|
59
|
+
1. Open the Developer Tools in Chrome (Cmd + Atl + J)
|
60
|
+
2. Click the Settings gear in the bottom right corner.
|
61
|
+
3. Click "Overrides" on the left side of the settings panel.
|
62
|
+
4. Check the "User Agent" checkbox.
|
63
|
+
6. Choose "Other..." from the User Agent dropdown.
|
64
|
+
7. Type `googlebot` into the input box.
|
65
|
+
8. Refresh the page (make sure to keep the developer tools open).
|
44
66
|
|
45
67
|
## License
|
46
68
|
|
data/Rakefile
CHANGED
data/lib/prerender_rails.rb
CHANGED
@@ -1,10 +1,30 @@
|
|
1
|
-
require "rack/version"
|
2
|
-
|
3
1
|
module Rack
|
4
2
|
class Prerender
|
5
3
|
require 'net/http'
|
6
4
|
|
7
|
-
def initialize(app)
|
5
|
+
def initialize(app, options={})
|
6
|
+
@crawler_user_agents = [
|
7
|
+
'googlebot',
|
8
|
+
'yahoo',
|
9
|
+
'bingbot',
|
10
|
+
'baiduspider'
|
11
|
+
]
|
12
|
+
|
13
|
+
@extensions_to_ignore = [
|
14
|
+
'.js',
|
15
|
+
'.css',
|
16
|
+
'.less',
|
17
|
+
'.png',
|
18
|
+
'.jpg',
|
19
|
+
'.jpeg',
|
20
|
+
'.gif',
|
21
|
+
'.pdf',
|
22
|
+
'.doc'
|
23
|
+
]
|
24
|
+
|
25
|
+
@options = options
|
26
|
+
@options[:whitelist] = [@options[:whitelist]] if @options[:whitelist].is_a? String
|
27
|
+
@options[:blacklist] = [@options[:blacklist]] if @options[:blacklist].is_a? String
|
8
28
|
@app = app
|
9
29
|
end
|
10
30
|
|
@@ -23,36 +43,53 @@ module Rack
|
|
23
43
|
end
|
24
44
|
|
25
45
|
def should_show_prerendered_page(env)
|
46
|
+
user_agent = env['HTTP_USER_AGENT']
|
47
|
+
return false if !user_agent
|
48
|
+
|
26
49
|
request = Rack::Request.new(env)
|
27
|
-
user_agent = env['HTTP_USER_AGENT'].downcase
|
28
50
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
51
|
+
#if it is not a bot...dont prerender
|
52
|
+
return false if !@crawler_user_agents.include?(user_agent.downcase)
|
53
|
+
|
54
|
+
#if it is a bot and is requesting a resource...dont prerender
|
55
|
+
return false if @extensions_to_ignore.any? { |extension| request.path.include? extension }
|
56
|
+
|
57
|
+
#if it is a bot and not requesting a resource and is not whitelisted...dont prerender
|
58
|
+
return false if @options[:whitelist].is_a?(Array) && @options[:whitelist].all? { |whitelisted| !request.path.include? whitelisted }
|
33
59
|
|
34
|
-
|
60
|
+
#if it is a bot and not requesting a resource and is not blacklisted(url or referer)...dont prerender
|
61
|
+
if @options[:blacklist].is_a?(Array) && @options[:blacklist].any? { |blacklisted|
|
62
|
+
blacklistedUrl = false
|
63
|
+
blacklistedReferer = false
|
35
64
|
|
36
|
-
|
37
|
-
|
38
|
-
!request.path.include?('.less') &&
|
39
|
-
!request.path.include?('.png') &&
|
40
|
-
!request.path.include?('.jpg') &&
|
41
|
-
!request.path.include?('.jpeg') &&
|
42
|
-
!request.path.include?('.gif')
|
65
|
+
blacklistedUrl = request.path.include? blacklisted
|
66
|
+
blacklistedReferer = request.referer.include? blacklisted if request.referer
|
43
67
|
|
44
|
-
|
68
|
+
blacklistedUrl || blacklistedReferer
|
69
|
+
}
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
|
73
|
+
return true
|
45
74
|
end
|
46
75
|
|
47
76
|
def get_prerendered_page_response(env)
|
48
77
|
begin
|
49
|
-
|
50
|
-
prerender_url = ENV['PRERENDER_URL'] || 'http://prerender.herokuapp.com/'
|
51
|
-
forward_slash = prerender_url[-1, 1] == '/' ? '' : '/'
|
52
|
-
Net::HTTP.get_response(URI.parse("#{prerender_url}#{forward_slash}#{url}"))
|
78
|
+
Net::HTTP.get_response(URI.parse(build_api_url(env)))
|
53
79
|
rescue
|
54
80
|
nil
|
55
81
|
end
|
56
82
|
end
|
83
|
+
|
84
|
+
def build_api_url(env)
|
85
|
+
url = Rack::Request.new(env).url
|
86
|
+
prerender_url = get_prerender_service_url()
|
87
|
+
forward_slash = prerender_url[-1, 1] == '/' ? '' : '/'
|
88
|
+
"#{prerender_url}#{forward_slash}#{url}"
|
89
|
+
end
|
90
|
+
|
91
|
+
def get_prerender_service_url
|
92
|
+
ENV['PRERENDER_SERVICE_URL'] || 'http://prerender.herokuapp.com/'
|
93
|
+
end
|
57
94
|
end
|
58
95
|
end
|
data/prerender_rails.gemspec
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'rack/version'
|
5
2
|
|
6
3
|
Gem::Specification.new do |spec|
|
7
4
|
spec.name = "prerender_rails"
|
8
|
-
spec.version =
|
5
|
+
spec.version = "0.0.3"
|
9
6
|
spec.authors = ["Todd Hooper"]
|
10
|
-
spec.email = ["
|
7
|
+
spec.email = ["todd@collectiveip.com"]
|
11
8
|
spec.description = %q{Rails middleware to prerender your javascript heavy pages on the fly by a phantomjs service}
|
12
9
|
spec.summary = %q{Prerender your backbone/angular/javascript rendered application on the fly when search engines crawl}
|
13
10
|
spec.homepage = "https://github.com/collectiveip/prerender_rails"
|
@@ -18,6 +15,9 @@ Gem::Specification.new do |spec|
|
|
18
15
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
16
|
spec.require_paths = ["lib"]
|
20
17
|
|
18
|
+
spec.add_dependency 'rack', '>= 0'
|
19
|
+
|
21
20
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
21
|
spec.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency "webmock"
|
23
23
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe Rack::Prerender do
|
4
|
+
|
5
|
+
bot = 'googlebot'
|
6
|
+
user = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36'
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
@app = lambda do |params|
|
10
|
+
[200, {}, ""]
|
11
|
+
end
|
12
|
+
|
13
|
+
@prerender = Rack::Prerender.new(@app)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return a prerendered reponse for a crawler" do
|
17
|
+
request = Rack::MockRequest.env_for "/", "HTTP_USER_AGENT" => bot
|
18
|
+
stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
|
19
|
+
response = Rack::Prerender.new(@app).call(request)
|
20
|
+
|
21
|
+
assert_equal response[2].body, ["<html></html>"]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should continue to app routes if user is not a bot by checking agent string" do
|
25
|
+
request = Rack::MockRequest.env_for "/", "HTTP_USER_AGENT" => user
|
26
|
+
response = Rack::Prerender.new(@app).call(request)
|
27
|
+
|
28
|
+
assert_equal response[2], ""
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should continue to app routes if user is a bot, but the bot is requesting a resource file" do
|
32
|
+
request = Rack::MockRequest.env_for "/main.js?anyQueryParam=true", "HTTP_USER_AGENT" => bot
|
33
|
+
response = Rack::Prerender.new(@app).call(request)
|
34
|
+
|
35
|
+
assert_equal response[2], ""
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should continue to app routes if the url is not part of the whitelist" do
|
39
|
+
request = Rack::MockRequest.env_for "/profile/blah", "HTTP_USER_AGENT" => bot
|
40
|
+
response = Rack::Prerender.new(@app, whitelist: ['/search', '/help']).call(request)
|
41
|
+
|
42
|
+
assert_equal response[2], ""
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return a prerendered response if the url is part of the whitelist" do
|
46
|
+
request = Rack::MockRequest.env_for "/search/things?query=blah", "HTTP_USER_AGENT" => bot
|
47
|
+
stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
|
48
|
+
response = Rack::Prerender.new(@app, whitelist: ['/search', '/help']).call(request)
|
49
|
+
|
50
|
+
assert_equal response[2].body, ["<html></html>"]
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should continue to app routes if the url is part of the blacklist" do
|
54
|
+
request = Rack::MockRequest.env_for "/search/things?query=blah", "HTTP_USER_AGENT" => bot
|
55
|
+
response = Rack::Prerender.new(@app, blacklist: ['/search', '/help']).call(request)
|
56
|
+
|
57
|
+
assert_equal response[2], ""
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should return a prerendered response if the url is not part of the blacklist" do
|
61
|
+
request = Rack::MockRequest.env_for "/profile/blah", "HTTP_USER_AGENT" => bot
|
62
|
+
stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
|
63
|
+
response = Rack::Prerender.new(@app, blacklist: ['/search', '/help']).call(request)
|
64
|
+
|
65
|
+
assert_equal response[2].body, ["<html></html>"]
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should continue to app routes if the referer is part of the blacklist" do
|
69
|
+
request = Rack::MockRequest.env_for "/api/results", "HTTP_USER_AGENT" => bot, "HTTP_REFERER" => '/search'
|
70
|
+
response = Rack::Prerender.new(@app, blacklist: ['/search', '/help']).call(request)
|
71
|
+
|
72
|
+
assert_equal response[2], ""
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should return a prerendered response if the referer is not part of the blacklist" do
|
76
|
+
request = Rack::MockRequest.env_for "/api/results", "HTTP_USER_AGENT" => bot, "HTTP_REFERER" => '/search'
|
77
|
+
stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
|
78
|
+
response = Rack::Prerender.new(@app, blacklist: ['/profile', '/help']).call(request)
|
79
|
+
|
80
|
+
assert_equal response[2].body, ["<html></html>"]
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#buildApiUrl' do
|
84
|
+
it "should build the correct api url with the default url" do
|
85
|
+
request = Rack::MockRequest.env_for "https://google.com/search?q=javascript"
|
86
|
+
assert_equal @prerender.build_api_url(request), 'http://prerender.herokuapp.com/https://google.com/search?q=javascript'
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should build the correct api url with an environment variable url" do
|
90
|
+
ENV['PRERENDER_SERVICE_URL'] = 'http://prerenderurl.com'
|
91
|
+
request = Rack::MockRequest.env_for "https://google.com/search?q=javascript"
|
92
|
+
assert_equal @prerender.build_api_url(request), 'http://prerenderurl.com/https://google.com/search?q=javascript'
|
93
|
+
ENV['PRERENDER_SERVICE_URL'] = nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prerender_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Todd Hooper
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,22 +52,38 @@ dependencies:
|
|
38
52
|
- - '>='
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webmock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
41
69
|
description: Rails middleware to prerender your javascript heavy pages on the fly
|
42
70
|
by a phantomjs service
|
43
71
|
email:
|
44
|
-
-
|
72
|
+
- todd@collectiveip.com
|
45
73
|
executables: []
|
46
74
|
extensions: []
|
47
75
|
extra_rdoc_files: []
|
48
76
|
files:
|
49
77
|
- .gitignore
|
78
|
+
- .travis.yml
|
50
79
|
- Gemfile
|
51
80
|
- LICENSE.txt
|
52
81
|
- README.md
|
53
82
|
- Rakefile
|
54
83
|
- lib/prerender_rails.rb
|
55
|
-
- lib/rack/version.rb
|
56
84
|
- prerender_rails.gemspec
|
85
|
+
- test/lib/prerender_rails.rb
|
86
|
+
- test/test_helper.rb
|
57
87
|
homepage: https://github.com/collectiveip/prerender_rails
|
58
88
|
licenses:
|
59
89
|
- MIT
|
@@ -79,4 +109,6 @@ signing_key:
|
|
79
109
|
specification_version: 4
|
80
110
|
summary: Prerender your backbone/angular/javascript rendered application on the fly
|
81
111
|
when search engines crawl
|
82
|
-
test_files:
|
112
|
+
test_files:
|
113
|
+
- test/lib/prerender_rails.rb
|
114
|
+
- test/test_helper.rb
|
data/lib/rack/version.rb
DELETED