prerender_rails 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 [](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