diff --git a/Gemfile.lock b/Gemfile.lock
index efa92a34d47faccb9f7145389826952d43e179f8..a7bce86fa26f68b3cb84438bc8c1902bfba992ce 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -123,17 +123,17 @@ GEM
     autoprefixer-rails (10.4.16.0)
       execjs (~> 2)
     aws-eventstream (1.3.0)
-    aws-partitions (1.883.0)
-    aws-sdk-core (3.190.3)
+    aws-partitions (1.887.0)
+    aws-sdk-core (3.191.0)
       aws-eventstream (~> 1, >= 1.3.0)
       aws-partitions (~> 1, >= 1.651.0)
       aws-sigv4 (~> 1.8)
       jmespath (~> 1, >= 1.6.1)
-    aws-sdk-kms (1.76.0)
-      aws-sdk-core (~> 3, >= 3.188.0)
+    aws-sdk-kms (1.77.0)
+      aws-sdk-core (~> 3, >= 3.191.0)
       aws-sigv4 (~> 1.1)
-    aws-sdk-s3 (1.142.0)
-      aws-sdk-core (~> 3, >= 3.189.0)
+    aws-sdk-s3 (1.143.0)
+      aws-sdk-core (~> 3, >= 3.191.0)
       aws-sdk-kms (~> 1)
       aws-sigv4 (~> 1.8)
     aws-sigv4 (1.8.0)
@@ -142,7 +142,7 @@ GEM
     bcrypt (3.1.20)
     bigdecimal (3.1.6)
     bindex (0.8.1)
-    bootsnap (1.17.1)
+    bootsnap (1.18.3)
       msgpack (~> 1.2)
     bootstrap (5.3.2)
       autoprefixer-rails (>= 9.1.0)
@@ -157,11 +157,11 @@ GEM
     builder (3.2.4)
     byebug (11.1.3)
     cancancan (3.3.0)
-    capybara (3.39.2)
+    capybara (3.40.0)
       addressable
       matrix
       mini_mime (>= 0.1.3)
-      nokogiri (~> 1.8)
+      nokogiri (~> 1.11)
       rack (>= 1.6.0)
       rack-test (>= 0.6.3)
       regexp_parser (>= 1.5, < 3.0)
@@ -186,7 +186,8 @@ GEM
       unaccent (~> 0.3)
     country_select (8.0.3)
       countries (~> 5.0)
-    crack (0.4.5)
+    crack (0.4.6)
+      bigdecimal
       rexml
     crass (1.0.6)
     csl (2.0.0)
@@ -392,11 +393,11 @@ GEM
     net-smtp (0.4.0.1)
       net-protocol
     nio4r (2.7.0)
-    nokogiri (1.16.0-arm64-darwin)
+    nokogiri (1.16.2-arm64-darwin)
       racc (~> 1.4)
-    nokogiri (1.16.0-x86_64-darwin)
+    nokogiri (1.16.2-x86_64-darwin)
       racc (~> 1.4)
-    nokogiri (1.16.0-x86_64-linux)
+    nokogiri (1.16.2-x86_64-linux)
       racc (~> 1.4)
     oauth2 (2.0.9)
       faraday (>= 0.17.3, < 3.0)
@@ -405,7 +406,8 @@ GEM
       rack (>= 1.2, < 4)
       snaky_hash (~> 2.0)
       version_gem (~> 1.1)
-    octokit (8.0.0)
+    octokit (8.1.0)
+      base64
       faraday (>= 1, < 3)
       sawyer (~> 0.9)
     omniauth (2.1.2)
@@ -436,7 +438,7 @@ GEM
     puma (6.4.2)
       nio4r (~> 2.0)
     racc (1.7.3)
-    rack (3.0.8)
+    rack (3.0.9)
     rack-mini-profiler (2.3.4)
       rack (>= 1.2.0)
     rack-protection (4.0.0)
@@ -585,7 +587,7 @@ GEM
       ethon (>= 0.9.0)
     tzinfo (2.0.6)
       concurrent-ruby (~> 1.0)
-    tzinfo-data (1.2023.4)
+    tzinfo-data (1.2024.1)
       tzinfo (>= 1.0.0)
     unaccent (0.4.0)
     unicode-display_width (2.5.0)
diff --git a/app/controllers/admin/communication/websites_controller.rb b/app/controllers/admin/communication/websites_controller.rb
index 6d64a22e32365347159ccbb4834e0c537985814d..d674653a8f63bff45649af56199a94ee3a9beab8 100644
--- a/app/controllers/admin/communication/websites_controller.rb
+++ b/app/controllers/admin/communication/websites_controller.rb
@@ -3,7 +3,7 @@ class Admin::Communication::WebsitesController < Admin::Communication::Websites:
   has_scope :for_about_type
 
   def index
-    @websites = apply_scopes(@websites).ordered.page(params[:page])
+    @websites = apply_scopes(@websites).ordered.page(params[:page]).per(24)
     breadcrumb
   end
 
@@ -59,6 +59,8 @@ class Admin::Communication::WebsitesController < Admin::Communication::Websites:
 
   def update
     if @website.update_and_sync(website_params)
+      # TODO better place, background job once w week?
+      @website.screenshot!
       redirect_to [:admin, @website], notice: t('admin.successfully_updated_html', model: @website.to_s)
     else
       breadcrumb
diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb
index aa6b81230c9ca12f7a2a765c4420e9776670a23f..cac6e7952aaf4f2a0fb17d4a3877f11cb0cbfb81 100644
--- a/app/models/communication/website.rb
+++ b/app/models/communication/website.rb
@@ -69,6 +69,7 @@ class Communication::Website < ApplicationRecord
   include WithReferences
   include WithSpecialPages
   include WithMenus # Menus must be created after special pages, so we can fill legal menu
+  include WithScreenshot
   include WithSecurity
   include WithStyle
   include WithTheme
diff --git a/app/models/communication/website/with_screenshot.rb b/app/models/communication/website/with_screenshot.rb
new file mode 100644
index 0000000000000000000000000000000000000000..014b85c0f31d2f2e606b71f267b9f17335e8a2f5
--- /dev/null
+++ b/app/models/communication/website/with_screenshot.rb
@@ -0,0 +1,13 @@
+module Communication::Website::WithScreenshot
+  extend ActiveSupport::Concern
+  
+  included do
+    has_one_attached :screenshot
+  end
+  
+  def screenshot!
+    screenshot_url = Screenshot.capture(url)
+    downloaded_image = URI.open(screenshot_url)
+    self.screenshot.attach(io: downloaded_image  , filename: "screenshot.png")
+  end
+end
\ No newline at end of file
diff --git a/app/services/screenshot.rb b/app/services/screenshot.rb
new file mode 100644
index 0000000000000000000000000000000000000000..37934418e00b07f7dcc25c95aafd02d40b1f2a04
--- /dev/null
+++ b/app/services/screenshot.rb
@@ -0,0 +1,31 @@
+class Screenshot
+  # https://microlink.io/docs/api/getting-started/overview
+  # https://api.microlink.io/?url=https://www.noesya.coop&screenshot=true&meta=false&device=Macbook%20Pro%2015
+  # {
+  #   "status": "success",
+  #   "data": {
+  #     "url": "https://www.noesya.coop/",
+  #     "screenshot": {
+  #       "size_pretty": "1.25 MB",
+  #       "size": 1253017,
+  #       "type": "png",
+  #       "url": "https://iad.microlink.io/9Yn0uu1Ajg4QX8uKdMqglHSQn0o5nfl9dQiyWfLGUcseMgcnpqjjj_YT0yDDSSnr4YF44cALFaYnEfDafjG09w.png",
+  #       "width": 2880,
+  #       "height": 1800
+  #     }
+  #   }
+  # }
+  def self.capture(url)
+    response = HTTParty.get('https://api.microlink.io', {
+      query: {
+        url: url,
+        screenshot: true,
+        meta: false,
+        waitUntil: 'load',
+        device: 'Macbook Pro 15'
+      }
+    })
+    data = JSON.parse(response.body)
+    data.dig('data', 'screenshot', 'url')
+  end
+end
\ No newline at end of file
diff --git a/app/views/admin/communication/websites/index.html.erb b/app/views/admin/communication/websites/index.html.erb
index 44dc1b675df84f808d8a17d21006d42658d09551..83cc050157f742796a0dad9ecffdc8cb2791f3a1 100644
--- a/app/views/admin/communication/websites/index.html.erb
+++ b/app/views/admin/communication/websites/index.html.erb
@@ -2,39 +2,21 @@
 
 <%= render 'filters', current_path: admin_communication_websites_path, filters: @filters if @filters.any?  %>
 
-<div class="table-responsive">
-  <table class="<%= table_classes %>">
-    <thead>
-      <tr>
-        <th><%= Communication::Website.human_attribute_name('name') %></th>
-        <th><%= Communication::Website.human_attribute_name('url') %></th>
-        <th><%= Communication::Website.human_attribute_name('about_type') %></th>
-        <th><%= Communication::Website.human_attribute_name('about') %></th>
-        <th></th>
-      </tr>
-    </thead>
-    <tbody>
-      <% @websites.each do |website| %>
-      <tr>
-        <td><%= link_to website, [:admin, website] %></td>
-        <td><%= link_to website.url, website.url, target: :_blank unless website.url.blank? %></td>
-        <td><%= I18n.t("activerecord.attributes.communication/website.about_#{website.about_type}") %></td>
-        <td><%= link_to_if can?(:read, website.about), website.about, [:admin, website.about] if website.about %></td>
-        <td class="text-end">
-          <div class="btn-group" role="group">
-            <%= edit_link website %>
-            <%= destroy_link website %>
-          </div>
-        </td>
-      </tr>
-      <% end %>
-    </tbody>
-  </table>
+<div class="row pt-5">
+  <% @websites.each do |website| %>
+    <div class="col-lg-4 col-xl-3">
+      <div class=" position-relative mb-5">
+        <div class="ratio bg-light" style="--bs-aspect-ratio: 62.5%">
+          <%= kamifusen_tag website.screenshot, width: 500, class:'img-fluid rounded border' if website.screenshot.attached? %>
+        </div>
+        <h2 class="p strong mt-2 mb-0"><%= website %></h2>
+        <%= link_to t('show'), [:admin, website], class: 'stretched-link pull-end' %>
+      </div>
+    </div>
+  <% end %>
 </div>
-
 <%= paginate @websites, theme: 'bootstrap-5' %>
 
-
 <% content_for :action_bar_right do %>
   <%= create_link Communication::Website %>
 <% end %>