8

If you google "will_paginate" and "ajax", the top result is this blog post: But the original author of will_paginate says to not use this method (bad for SEO/spiders) ...

But I cant get the original authors method to work (his javascript kills all my links). An other gentleman suggests a similar method to mislav's (the original will_paginate author) concept. But I cant get that to work either.

so .... what is the best way to paginate using AJAX, and stay SEO friendly? (for RAILS >2.1)

Scott
  • 6,411
  • 6
  • 39
  • 43
Etienne
  • 167
  • 1
  • 1
  • 6

5 Answers5

15

Tomh's answer is correct. Just for shiggles, I prototyped a quick implementation. Here's a screencast that shows it using Ajax when Javascript is enabled (your users) and still having pretty URLs when Javascript is disabled (Google). And here are a few code snippets to get you rolling on it.

config/routes.rb:

map.connect 'items/:page', :controller => "items", :action => "index", :page => 1

app/controllers/items_controller.rb:

class ItemsController < ApplicationController
  def index
    @items = Item.paginate(:all, :page => params[:page])

    respond_to do |format|
      format.html
      format.js do
        render :update do |page|
          page.replace_html :items, :partial => "items"
          page << "ajaxifyPagination();"
        end
      end
    end
  end
end

app/views/items/index.html.erb:

<h1>Listing items</h1>

<div id="items">
  <%= render :partial => "items" %>
</div>

app/views/items/_items.html.erb:

<%= will_paginate @items %>

<table>
  <% for item in @items %>
    <tr>
      <td><%= item.id %></td>
    </tr>
  <% end %>
</table>

layout:

<%= javascript_include_tag :defaults %>

public/javascripts/application.js:

$(document).ready(function() {
    ajaxifyPagination();
});

function ajaxifyPagination() {
    $(".pagination a").click(function() {
        $.ajax({
          type: "GET",
          url: $(this).attr("href"),
          dataType: "script"
        });
        return false;
    });
}

My example uses jQuery (with jRails), but it's straightforward to do with Prototype as well.

Ian Terrell
  • 10,667
  • 11
  • 45
  • 66
  • 3
    +1 for 'shiggles' - you can learn new terminology every day. Oh, good answer too – DanSingerman Feb 20 '09 at 00:31
  • Hi Ian I tried implementing this code. I have 2 questions. 1. map.connect 'items/:page', :controller => "items", :action => "index", :page => 1 throws me an error saying "undefined variable map". One more error, I am having a index view that renders a partial _browser, that in turn renders a partial _listing which is wrapped in a div called "updated_ics_per_table" . So I am using $("#update_ics_per_table".pagination a"). It doesn't come inside this function. Please help me out here. – ramya Jan 16 '12 at 11:23
  • @ramya: Ian's answer is specific to Rails 2 and a some of the code has since been deprecated in Rails 3+. – James Feb 08 '12 at 22:06
7

Seo friendly and unobtrusive javascript goes hand in hand. What you can do is the following.

  • Code the entire site as if only html is enabled (incl your pagination thing)
  • Use respond_to and serve only the list of items if the request comes in from js
  • Using onDomReady from whatever library you pick you attempt to catch all pagination links and add an onclick event which triggers an ajax call to that new view and returns the result. You put that result into the container containing the data you are paginating. The onclick then returns false.
  • To give your users a better user experience you can add some features like active links etc to the same javascript method.

Using this approach the pagination will work for JS and non-js as the non-js users (including Googlebot) will traverse your pagination as normal. Only in the event that the user has javascript enabled, the container with data will be updated with new results.

TomHastjarjanto
  • 5,386
  • 1
  • 29
  • 41
  • "Create a view and map a route to it." should be: use respond_to and serve only the list of items if the request comes in from js. – Andrew Vit Feb 19 '09 at 22:53
1

Unfortunately, I don't think you can use Ajax in the way you want and still stay SEO friendly as far as the paginated content. The problem is that the robots of Google and friends, as far as I know, won't go through your content using XHR requests so they simply won't see that content.

That said, if the paginated items each have their own static, SEO-friendly pages (or are otherwise statically available on your site), the content will still find its way into their engines. This is the way you'll probably want to go.

0

There is a railscasts on this topic which helped me out http://railscasts.com/episodes/174-pagination-with-ajax

I'm running rails 3.2, so I added the pagination.js there mentioned to app/assets/javascripts folder

pagination.js

 $(function() {
    $(".pagination a").live("click", function() {
        $(".pagination").html("Loading...");
        $.getScript(this.href);
        return false;
    });
});

And then created

home.js.erb

$('#div_tags_list').html('<%= escape_javascript(render partial: '/customersb2b/user_customer_numbers_list').html_safe %>')
$('#receipts_list').html('<%= escape_javascript(render partial: '/customersb2b/feed').html_safe %>')

Since I have two distinct listings on my homepage.

This is all I had to do to put will_paginate working with Ajax. As for the SEO concerns, well, I don't know much about it, but the URL http://localhost:3000/customers?_=1366372168315&feed_page=1&tags_page=2 still works

MrWater
  • 1,797
  • 4
  • 20
  • 47
0

There is a great way to do this easily if not worried about spiders. Took me 5 minutes. Check out:

https://github.com/ronalchn/ajax_pagination/wiki/Adding-AJAX-to-will_paginate

If you get an error about a missing 'history' file, install:

https://github.com/wweidendorf/jquery-historyjs

but also be aware of:

rails ajax_pagination couldn't find file 'history'

Community
  • 1
  • 1
Abram
  • 39,950
  • 26
  • 134
  • 184