Skeleton Shared Partial

1. Copy shared partial files

Download all 1 shared partial files as a ZIP file.

Download all files (ZIP)

After downloading, unzip and copy the skeleton/ folder to your app/views/shared/components/ directory.

Copy these files to your app/views/shared/components/skeleton/ directory:

2. Usage example

<!-- Basic text skeleton (single line) -->
<%= render "shared/components/skeleton/skeleton" %>

<!-- Multiple text lines -->
<%= render "shared/components/skeleton/skeleton", count: 3 %>

<!-- Circle skeleton (avatar placeholder) -->
<%= render "shared/components/skeleton/skeleton", variant: "circle" %>

<!-- Larger circle -->
<%= render "shared/components/skeleton/skeleton",
  variant: "circle",
  width: "w-16",
  height: "h-16" %>

<!-- Rectangle skeleton -->
<%= render "shared/components/skeleton/skeleton", variant: "rectangle" %>

<!-- Image skeleton -->
<%= render "shared/components/skeleton/skeleton", variant: "image" %>

<!-- Button skeleton -->
<%= render "shared/components/skeleton/skeleton", variant: "button" %>

<!-- Input skeleton -->
<%= render "shared/components/skeleton/skeleton", variant: "input" %>

<!-- Custom dimensions -->
<%= render "shared/components/skeleton/skeleton",
  width: "w-3/4",
  height: "h-6" %>

<!-- Half-width text -->
<%= render "shared/components/skeleton/skeleton", width: "w-1/2" %>

<!-- Custom rounded -->
<%= render "shared/components/skeleton/skeleton",
  variant: "rectangle",
  rounded: "xl" %>

<!-- No animation (static) -->
<%= render "shared/components/skeleton/skeleton",
  variant: "text",
  animated: false %>

<!-- Custom classes -->
<%= render "shared/components/skeleton/skeleton",
  variant: "rectangle",
  classes: "shadow-sm" %>

<!-- Card skeleton composition -->
<div class="bg-white w-full dark:bg-neutral-800 border border-black/10 dark:border-white/10 rounded-xl p-4 max-w-sm">
  <%= render "shared/components/skeleton/skeleton", variant: "image", classes: "mb-4" %>
  <%= render "shared/components/skeleton/skeleton", width: "w-3/4", height: "h-6", classes: "mb-3" %>
  <%= render "shared/components/skeleton/skeleton", count: 3 %>
</div>

<!-- User profile skeleton composition -->
<div class="flex items-center space-x-3">
  <div class="animate-pulse">
    <%= render "shared/components/skeleton/skeleton", variant: "circle" %>
  </div>
  <div class="flex-1 animate-pulse">
    <%= render "shared/components/skeleton/skeleton", width: "w-1/3", classes: "mb-2" %>
    <%= render "shared/components/skeleton/skeleton", width: "w-1/2", height: "h-3" %>
  </div>
</div>

<!-- Form skeleton composition -->
<div class="space-y-4 max-w-md animate-pulse">
  <div>
    <%= render "shared/components/skeleton/skeleton", width: "w-20", classes: "mb-2" %>
    <%= render "shared/components/skeleton/skeleton", variant: "input" %>
  </div>
  <div>
    <%= render "shared/components/skeleton/skeleton", width: "w-24", classes: "mb-2" %>
    <%= render "shared/components/skeleton/skeleton", variant: "input" %>
  </div>
  <div class="flex space-x-3">
    <%= render "shared/components/skeleton/skeleton", variant: "button" %>
    <%= render "shared/components/skeleton/skeleton", variant: "button", width: "w-20" %>
  </div>
</div>

Rendered usage example

Skeleton ViewComponent

1. Ensure the gem is installed

gem "view_component", "~> 4.2"

2. Copy component files

Download all 2 component files as a ZIP file.

Download all files (ZIP)

After downloading, unzip and copy the skeleton/ folder to your app/components/ directory.

Copy these files to your app/components/skeleton/ directory:

3. Usage example

<!-- Basic text skeleton (single line) -->
<%= render Skeleton::Component.new %>

<!-- Multiple text lines -->
<%= render Skeleton::Component.new(count: 3) %>

<!-- Circle skeleton (avatar placeholder) -->
<%= render Skeleton::Component.new(variant: :circle) %>

<!-- Larger circle -->
<%= render Skeleton::Component.new(
  variant: :circle,
  width: "w-16",
  height: "h-16"
) %>

<!-- Rectangle skeleton -->
<%= render Skeleton::Component.new(variant: :rectangle) %>

<!-- Image skeleton -->
<%= render Skeleton::Component.new(variant: :image) %>

<!-- Button skeleton -->
<%= render Skeleton::Component.new(variant: :button) %>

<!-- Input skeleton -->
<%= render Skeleton::Component.new(variant: :input) %>

<!-- Custom dimensions -->
<%= render Skeleton::Component.new(
  width: "w-3/4",
  height: "h-6"
) %>

<!-- Half-width text -->
<%= render Skeleton::Component.new(width: "w-1/2") %>

<!-- Custom rounded -->
<%= render Skeleton::Component.new(
  variant: :rectangle,
  rounded: :xl
) %>

<!-- No animation (static) -->
<%= render Skeleton::Component.new(
  variant: :text,
  animated: false
) %>

<!-- Custom classes -->
<%= render Skeleton::Component.new(
  variant: :rectangle,
  classes: "shadow-sm"
) %>

<!-- Card skeleton composition -->
<div class="bg-white w-full dark:bg-neutral-800 border border-black/10 dark:border-white/10 rounded-xl p-4 max-w-sm">
  <%= render Skeleton::Component.new(variant: :image, classes: "mb-4") %>
  <%= render Skeleton::Component.new(width: "w-3/4", height: "h-6", classes: "mb-3") %>
  <%= render Skeleton::Component.new(count: 3) %>
</div>

<!-- User profile skeleton composition -->
<div class="flex items-center space-x-3">
  <div class="animate-pulse">
    <%= render Skeleton::Component.new(variant: :circle) %>
  </div>
  <div class="flex-1 animate-pulse">
    <%= render Skeleton::Component.new(width: "w-1/3", classes: "mb-2") %>
    <%= render Skeleton::Component.new(width: "w-1/2", height: "h-3") %>
  </div>
</div>

<!-- Form skeleton composition -->
<div class="space-y-4 max-w-md animate-pulse">
  <div>
    <%= render Skeleton::Component.new(width: "w-20", classes: "mb-2") %>
    <%= render Skeleton::Component.new(variant: :input) %>
  </div>
  <div>
    <%= render Skeleton::Component.new(width: "w-24", classes: "mb-2") %>
    <%= render Skeleton::Component.new(variant: :input) %>
  </div>
  <div class="flex space-x-3">
    <%= render Skeleton::Component.new(variant: :button) %>
    <%= render Skeleton::Component.new(variant: :button, width: "w-20") %>
  </div>
</div>

Rendered usage example

Skeleton Rails Components

Display a preview of your content before the data gets loaded to reduce load-time frustration.

Examples

Basic Skeleton

A simple skeleton with two text lines of different widths.

<div class="animate-pulse max-w-md w-full">
  <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-full mb-2"></div>
  <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-1/2"></div>
</div>

Card Skeleton

A card layout skeleton with image, title, content, and footer areas.

<div class="animate-pulse max-w-md w-full">
  <div class="bg-white dark:bg-neutral-800 border border-black/10 dark:border-white/10 rounded-xl shadow-xs overflow-hidden px-4 py-5 sm:p-6">
    <!-- Image placeholder -->
    <div class="h-48 bg-neutral-200 dark:bg-neutral-700 rounded-lg mb-4"></div>

    <!-- Title -->
    <div class="h-6 bg-neutral-200 dark:bg-neutral-700 rounded w-3/4 mb-3"></div>

    <!-- Content lines -->
    <div class="space-y-2">
      <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-full"></div>
      <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-5/6"></div>
      <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-4/6"></div>
    </div>

    <!-- Footer -->
    <div class="flex items-center justify-between mt-4">
      <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-1/4"></div>
      <div class="h-8 bg-neutral-200 dark:bg-neutral-700 rounded w-20"></div>
    </div>
  </div>
</div>

Avatar Skeleton

A skeleton for user profiles with avatar and text content.

<div class="animate-pulse max-w-md w-full">
  <div class="flex items-center space-x-3">
    <!-- Avatar placeholder -->
    <div class="h-10 w-10 bg-neutral-200 dark:bg-neutral-700 rounded-full"></div>

    <!-- Text content -->
    <div class="flex-1">
      <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-1/3 mb-2"></div>
      <div class="h-3 bg-neutral-200 dark:bg-neutral-700 rounded w-1/2"></div>
    </div>
  </div>
</div>

Table Skeleton

A data table skeleton with header and multiple rows.

<div class="animate-pulse max-w-md w-full">
  <div class="bg-white dark:bg-neutral-800 border border-black/10 dark:border-white/10 rounded-xl shadow-xs overflow-hidden">
    <!-- Header -->
    <div class="bg-neutral-50 dark:bg-neutral-900 px-6 py-3 border-b border-neutral-200 dark:border-neutral-700">
      <div class="flex space-x-4">
        <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-20"></div>
        <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-24"></div>
        <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-16"></div>
        <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-20"></div>
      </div>
    </div>

    <!-- Rows -->
    <div class="divide-y divide-neutral-200 dark:divide-neutral-700">
      <% 5.times do %>
        <div class="px-6 py-4">
          <div class="flex space-x-4">
            <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-20"></div>
            <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-24"></div>
            <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-16"></div>
            <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-20"></div>
          </div>
        </div>
      <% end %>
    </div>
  </div>
</div>

Form Skeleton

A form skeleton with labels, inputs, textarea, checkbox, and buttons.

<div class="animate-pulse max-w-md w-full">
  <div class="space-y-6">
    <!-- Form group 1 -->
    <div>
      <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-20 mb-2"></div>
      <div class="h-10 bg-neutral-200 dark:bg-neutral-700 rounded w-full"></div>
    </div>

    <!-- Form group 2 -->
    <div>
      <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-24 mb-2"></div>
      <div class="h-10 bg-neutral-200 dark:bg-neutral-700 rounded w-full"></div>
    </div>

    <!-- Form group 3 -->
    <div>
      <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-32 mb-2"></div>
      <div class="h-24 bg-neutral-200 dark:bg-neutral-700 rounded w-full"></div>
    </div>

    <!-- Checkbox -->
    <div class="flex items-center space-x-2">
      <div class="size-4 bg-neutral-200 dark:bg-neutral-700 rounded"></div>
      <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-40"></div>
    </div>

    <!-- Buttons -->
    <div class="flex space-x-3">
      <div class="h-10 bg-neutral-200 dark:bg-neutral-700 rounded w-24"></div>
      <div class="h-10 bg-neutral-200 dark:bg-neutral-700 rounded w-20"></div>
    </div>
  </div>
</div>

List Skeleton

A list skeleton with avatars, content, and action items.

<div class="animate-pulse max-w-md w-full">
  <div class="space-y-4">
    <% 4.times do %>
      <div class="flex items-center space-x-3 p-3 bg-white dark:bg-neutral-800 border border-black/10 dark:border-white/10 rounded-xl shadow-xs overflow-hidden">
        <!-- Avatar -->
        <div class="h-10 w-10 bg-neutral-200 dark:bg-neutral-700 rounded-full flex-shrink-0"></div>

        <!-- Content -->
        <div class="flex-1 min-w-0">
          <div class="h-4 bg-neutral-200 dark:bg-neutral-700 rounded w-3/4 mb-2"></div>
          <div class="h-3 bg-neutral-200 dark:bg-neutral-700 rounded w-1/2"></div>
        </div>

        <!-- Action -->
        <div class="size-6 bg-neutral-200 dark:bg-neutral-700 rounded flex-shrink-0"></div>
      </div>
    <% end %>
  </div>
</div>

Table of contents

Powered by

Get notified when new components come out