0.0
The project is in a healthy, maintained state
Provides customizable, responsive skeleton loaders for Rails views.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Runtime

>= 5.0.0
 Project Readme

Skeleton Loader

Gem Version CircleCI Test Coverage: 100% MIT License

Skeleton Loader is a Ruby on Rails gem for creating animated placeholders that enhance loading states. Whether rendered through Rails views or dynamically with JavaScript, these skeletons provide a seamless visual experience while content loads.

⚠ Note: Skeleton Loader is an experimental gem currently in early development, exploring the possibilities in the magical world of Rails gems. While loaders are ideally handled client-side, this gem aims to make it easy to add placeholders directly within the Rails realm.


Table of Contents

  • Features
  • Installation
  • Quick Start
  • Usage
  • JavaScript Integration
  • Configuration
  • Code Quality
  • Roadmap
  • Contributing
  • License

1

Features

  • 🚀 Seamless Rails integration: Enhances loading transitions with minimal setup.
  • 🔨 Universal skeletons: Creates loading states in Rails views & JavaScript.
  • ⚙️ Consistency: Unified templates & options across both environments.
  • Lightweight & fast: Designed to be fast and easy to implement with minimal dependencies.

Installation

To install Skeleton Loader, add the following line to your Gemfile:

gem "skeleton-loader"

Then, execute:

bundle install

Requirements

  • Ruby 2.5 or higher
  • Rails 5.0 or higher
  • Asset Pipeline (for CSS handling)

Install Templates

Add predefined templates to your app with:

rails generate skeleton_loader:add_templates

This command will place templates in app/views/skeleton_loader/, which you can customize as needed.

And in case needed, you can revert to default templates by running:

rails generate skeleton_loader:reset_templates

Quick Start

Quickly integrate Skeleton Loader into your Rails app with these steps:

  1. Include Assets

    • Rails 7 (Import Maps):

      • In config/importmap.rb, add:
        pin "skeleton-loader", to: "skeleton_loader.js"
      • In your JavaScript entry file, add:
        import SkeletonLoader from "skeleton-loader"
    • In app/assets/stylesheets/application.css, add:

      *= require skeleton_loader
    • Rails 6 (Webpack):

      • Run:
        npm install "@ersync/skeleton-loader"
      • In your JavaScript entry file, add:
        import SkeletonLoader from "skeleton-loader"
    • Rails 5 (Asset Pipeline):

      • In app/assets/javascripts/application.js, add:
        //= require skeleton_loader
      • In app/assets/stylesheets/application.css, add:
        *= require skeleton_loader
  2. Use in Views

    Use the skeleton_loader helper next to the content that loads slowly. Set content_id to the target element's ID and choose a type for the skeleton template.

    Example:

    <div id="content-element">
      <!-- Content that takes time to load -->
    </div>
    <%= skeleton_loader(content_id: 'content-element', type: "card") %>

For more detailed instructions, refer to Usage section.


Usage

The gem provides a primary view helper, skeleton_loader, which generates a div containing a skeleton next to the targeted content element. This skeleton will be hidden once the content element fully loads, providing a seamless loading experience.

Pre-defined Templates

Specify content_id and, optionally, a template type and customization options.

<%= skeleton_loader(content_id: 'content-element', 
  type: "card",
  count: 5,
  scale: 1.2,
  animation_type: 'animation-pulse') %>

Custom Skeletons with a Block

Define your own HTML structure in a block. Note that type and options are not used.

<%= skeleton_loader(content_id: 'content-element') do %>
  <div class="custom-skeleton">
    <div class="avatar skeleton-circle"></div>
    <div class="text-lines"></div>
  </div>
<% end %>

See Configuration for all available options.


JavaScript Integration

Skeleton Loader also provides a JavaScript API to dynamically create skeletons independently of Rails views.

💡 You only need this API if you're loading content asynchronously i.e. AJAX calls. For standard Rails views, use the Rails helper method instead.

1. Basic Setup

First, initialize the SkeletonLoader in your JavaScript:

const skeleton = new SkeletonLoader();

2. Creating Skeletons

There are two methods for creating skeletons using JavaScript:

Using Pre-defined Templates

const loader = skeleton.render({
  contentId,                    // Required. ID of the element to replace with skeleton
  ...options                    // Optional. See configuration section for available options
});

Creating Custom Skeletons

const loader = skeleton.renderCustom({
  contentId,                    // Required. ID of the element to replace with skeleton
  markup                        // Required. Custom HTML string for skeleton content
});

3. Managing Loading States

Each skeleton instance (both render() and renderCustom()) returns an object with these methods:

  • isLoading(): Returns the current loading state
  • reveal(): Removes skeleton and displays content
// Check if still loading
if (loader.isLoading()) {
  // Do something while content loads
}

// Remove skeleton and show content
loader.reveal();
Practical Examples

Here's some example showing how to use the skeleton loader with an API call:

async function loadUserProfile(userId) {
  // Create skeleton while loading
  const loader = skeleton.render({
    contentId: 'content-element',
    type: 'profile'
  });

  try {
    // Fetch your data
    const response = await fetch(`/api/users/${userId}`);
    const userData = await response.json();

    // Update the DOM with your content
    document.getElementById('content-element').innerHTML = createUserProfile(userData);

    // Remove the skeleton
    loader.reveal();
  } catch (error) {
    console.error('Failed to load user profile:', error);
    loader.reveal(); // Always cleanup the skeleton
  }
}
async function loadDashboard() {
  // Create multiple skeletons
  const loaders = {
    profile: skeleton.render({ contentId: 'profile', type: 'profile', scale:1.2, width:250 }),
    stats: skeleton.render({ contentId: 'stats', type: 'card', scale:1.3, animationType:"sl-flow" }),
    activities: skeleton.render({ contentId: 'activities', type: 'list' })
  };

  // Load your data
  const [profileData, statsData, activitiesData] = await Promise.all([
    fetchProfile(),
    fetchStats(),
    fetchActivities()
  ]);

  // Update content and reveal each section
  updateProfile(profileData);
  loaders.profile.reveal();

  updateStats(statsData);
  loaders.stats.reveal();

  updateActivities(activitiesData);
  loaders.activities.reveal();
}

Configuration

Options

The following options can be passed to both the Rails view helper and JavaScript API. Note that Rails uses snake_case (e.g., animation_type), while JavaScript uses camelCase (e.g., animationType).

Option Type Description Default Example
content_id String Unique identifier for the skeleton loader container nil "content-element"
type String Predefined template type (e.g., "product", "profile") "default" "product"
width Integer Base width of a single skeleton item in pixels Depends on type 250
count Integer Number of skeleton items to render Depends on type 6
per_row Integer Number of skeleton items displayed per row Depends on type 4
scale Float Size multiplier for all skeleton item dimensions 1.0 1.2
animation_type String Type of loading animation "sl-gradient" "sl-glow"

Notes:

  • type determines default layout and styling
  • scale affects width and spacing proportionally
  • animation_type supports different loading effect styles

Available Templates

Skeleton Loader comes with several pre-built templates, each with their default configurations:

Template Type Default Width Count Items Per Row
card 200px 3 3
comment 900px 2 1
default 900px 1 1
gallery 320px 3 3
paragraph 900px 1 1
product 320px 3 3
profile 320px 3 3

For an interactive preview of available templates and animations, visit the Live Demo.

Available Animations

Choose from several animation styles to match your design:

  • sl-gradient (default): Smooth gradient movement
  • sl-shine: Shimmer effect
  • sl-pulse: Fade in/out
  • sl-flow: Continuous flow
  • sl-neon: Subtle glow
  • sl-breathing: Gentle scaling

Application Defaults

To set application-wide defaults, create config/initializers/skeleton_loader.rb:

SkeletonLoader.configure do |config|
  # Override default template settings
  config.templates[:product] = {
          width: 400,
          count: 6,
          per_row: 3
  }
  # Global settings
  config.scale = 1.0                     # Default: 1.0
  config.animation_type = "sl-gradient"  # Default: "sl-gradient"
end

Advanced Configuration

For applications requiring custom HTML elements or styles:

SkeletonLoader.configure do |config|
  config.additional_allowed_tags = []                  # Default: []
  config.additional_allowed_attributes = {}            # Default: {}
  config.additional_allowed_css_properties = []        # Default: []
end

Code Quality

Skeleton Loader maintains code quality through:

  • RSpec: Comprehensive tests covering core functionality.
  • CircleCI: Continuous integration ensures all new changes meet quality standards.
  • Rubocop: Consistent linting aligns code with Ruby community conventions.

Roadmap

Here are some features I'd like to add when I have time:

  • New Templates & Animations: Expanding template and animation options.
  • Turbo & Stimulus Support: Enhancing compatibility with Rails Turbo and StimulusJS.
  • Builder Helper for Custom Skeletons:: Introducing a helper to easily create custom skeletons (e.g., circles, rectangles, etc.) with customizable options, simplifying the process of designing custom skeletons.

Suggestions and contributions are welcome!


Contributing

To contribute:

  1. Fork the repository.
  2. Create a new feature branch.
  3. Add tests for new features.
  4. Commit your changes and submit a pull request.

Please follow the Code of Conduct for all contributions.


License

Skeleton Loader is licensed under the MIT License. See LICENSE for details.