diff --git a/lib/tiny_admin/views/components/pagination.rb b/lib/tiny_admin/views/components/pagination.rb
index 1f8d8d9..d1997a3 100644
--- a/lib/tiny_admin/views/components/pagination.rb
+++ b/lib/tiny_admin/views/components/pagination.rb
@@ -16,17 +16,38 @@ def template
           div(class: 'pagination-div') {
             nav('aria-label' => 'Pagination') {
               ul(class: 'pagination justify-content-center') {
-                1.upto(pages) do |i|
-                  li_class = (i == current ? 'page-item active' : 'page-item')
-                  li(class: li_class) {
-                    href = query_string.empty? ? "?p=#{i}" : "?#{query_string}&p=#{i}"
-                    a(class: 'page-link', href: href) { i }
-                  }
+                if pages <= 10
+                  pages_range(1..pages)
+                elsif current <= 4 || current >= pages - 3
+                  pages_range(1..(current <= 4 ? current + 2 : 4), with_dots: true)
+                  pages_range((current > pages - 4 ? current - 2 : pages - 2)..pages)
+                else
+                  pages_range(1..1, with_dots: true)
+                  pages_range(current - 2..current + 2, with_dots: true)
+                  pages_range(pages..pages)
                 end
               }
             }
           }
         end
+
+        private
+
+        def pages_range(range, with_dots: false)
+          range.each do |page|
+            li(class: page == current ? 'page-item active' : 'page-item') {
+              href = query_string.empty? ? "?p=#{page}" : "?#{query_string}&p=#{page}"
+              a(class: 'page-link', href: href) { page }
+            }
+          end
+          dots if with_dots
+        end
+
+        def dots
+          li(class: 'page-item disabled') {
+            a(class: 'page-link') { '...' }
+          }
+        end
       end
     end
   end
diff --git a/spec/dummy/config/tiny_admin.yml b/spec/dummy/config/tiny_admin.yml
index e831656..04780f9 100644
--- a/spec/dummy/config/tiny_admin.yml
+++ b/spec/dummy/config/tiny_admin.yml
@@ -29,6 +29,7 @@ sections:
     type: resource
     model: Post
     index:
+      pagination: 5
       attributes:
         - id
         - title
diff --git a/spec/features/components/pagination_spec.rb b/spec/features/components/pagination_spec.rb
index 3e7787b..991975f 100644
--- a/spec/features/components/pagination_spec.rb
+++ b/spec/features/components/pagination_spec.rb
@@ -3,10 +3,28 @@
 require 'rails_helper'
 
 RSpec.describe 'Pagination component', type: :feature do
-  before { setup_data }
+  def page_links
+    find_all('a.page-link').map(&:text)
+  end
 
-  context 'when clicking the Posts navbar link' do
+  context 'with a collection with less than 10 pages' do
     before do
+      setup_data(posts_count: 15)
+      visit '/admin'
+      log_in
+      click_link('Posts')
+    end
+
+    it 'shows the pagination widget', :aggregate_failures do
+      expect(page).to have_css('ul', class: 'pagination')
+      expect(page).to have_link('1', class: 'page-link', href: '?p=1')
+      expect(page_links).to eq(['1', '2', '3'])
+    end
+  end
+
+  context 'with a collection with more than 10 pages' do
+    before do
+      setup_data(posts_count: 60)
       visit '/admin'
       log_in
     end
@@ -15,9 +33,20 @@
       click_link('Posts')
 
       expect(page).to have_css('ul', class: 'pagination')
-      expect(page).to have_link('1', class: 'page-link', href: '?p=1')
-      expect(page).to have_link('2', class: 'page-link', href: '?p=2')
-      expect(page).to have_link('3', class: 'page-link', href: '?p=3')
+      expect(page).to have_link('1', class: 'page-link', href: '?p=12')
+      expect(page_links).to eq(['1', '2', '3', '...', '10', '11', '12'])
+    end
+
+    context 'when opening a specific page' do
+      before do
+        visit '/admin/posts?p=6'
+      end
+
+      it 'shows the pagination widget', :aggregate_failures do
+        expect(page).to have_css('ul', class: 'pagination')
+        expect(page).to have_link('6', class: 'page-link', href: '?p=6')
+        expect(page_links).to eq(['1', '...', '4', '5', '6', '7', '8', '...', '12'])
+      end
     end
   end
 end
diff --git a/spec/features/resources_spec.rb b/spec/features/resources_spec.rb
index b6943f5..e145a16 100644
--- a/spec/features/resources_spec.rb
+++ b/spec/features/resources_spec.rb
@@ -42,6 +42,7 @@
 
   context "when filtering by title in the post's listing page" do
     before do
+      setup_data(posts_count: 15)
       visit '/admin/posts?some_var=1'
       log_in
     end
diff --git a/spec/support/setup_data.rb b/spec/support/setup_data.rb
index 4a1cfe1..6d6dcb0 100644
--- a/spec/support/setup_data.rb
+++ b/spec/support/setup_data.rb
@@ -1,17 +1,17 @@
 # frozen_string_literal: true
 
 RSpec.shared_context 'with some data' do
-  def setup_data
-    5.times do
-      # Authors
+  def setup_data(posts_count: 5)
+    # Authors
+    authors = Array.new(3) do
       author_ref = Author.count + 1
-      author = Author.create!(name: "An author #{author_ref}", age: 24 + (author_ref * 3), email: "aaa#{author_ref}@bbb.ccc")
+      Author.create!(name: "An author #{author_ref}", age: 24 + (author_ref * 3), email: "aaa#{author_ref}@bbb.ccc")
+    end
 
-      # Posts
+    # Posts
+    posts_count.times do |i|
       post_ref = Post.count + 1
-      5.times do |i|
-        Post.create!(author: author, title: "A post #{post_ref + i}", description: 'Some post content')
-      end
+      Post.create!(author: authors[i % 3], title: "A post #{post_ref + i}", description: 'Some post content')
     end
   end
 end
