Skip to main content
The Skeleton component displays an animated placeholder while content is loading. It provides visual feedback to users during data fetching or processing.

Basic Usage

import reflex_ui as ui

ui.skeleton(class_name="h-4 w-64 rounded")

Common Patterns

Text Skeleton

rx.vstack(
    ui.skeleton(class_name="h-4 w-full rounded"),
    ui.skeleton(class_name="h-4 w-5/6 rounded"),
    ui.skeleton(class_name="h-4 w-4/6 rounded"),
    spacing="0.5rem"
)

Card Skeleton

rx.box(
    rx.vstack(
        ui.skeleton(class_name="h-48 w-full rounded-lg"),  # Image
        ui.skeleton(class_name="h-6 w-3/4 rounded"),       # Title
        ui.skeleton(class_name="h-4 w-full rounded"),       # Description line 1
        ui.skeleton(class_name="h-4 w-5/6 rounded"),       # Description line 2
        spacing="1rem"
    ),
    padding="1.5rem",
    border="1px solid var(--gray-4)",
    border_radius="0.5rem"
)

Avatar Skeleton

ui.skeleton(class_name="size-12 rounded-full")

Button Skeleton

ui.skeleton(class_name="h-10 w-24 rounded-md")

Profile Skeleton

rx.hstack(
    ui.skeleton(class_name="size-12 rounded-full"),  # Avatar
    rx.vstack(
        ui.skeleton(class_name="h-4 w-32 rounded"),   # Name
        ui.skeleton(class_name="h-3 w-24 rounded"),   # Email
        spacing="0.5rem",
        align_items="flex-start"
    ),
    spacing="1rem"
)

Table Skeleton

rx.vstack(
    # Header
    rx.hstack(
        ui.skeleton(class_name="h-4 w-24 rounded"),
        ui.skeleton(class_name="h-4 w-32 rounded"),
        ui.skeleton(class_name="h-4 w-20 rounded"),
        spacing="1rem",
        width="100%"
    ),
    # Rows
    *[
        rx.hstack(
            ui.skeleton(class_name="h-4 w-24 rounded"),
            ui.skeleton(class_name="h-4 w-32 rounded"),
            ui.skeleton(class_name="h-4 w-20 rounded"),
            spacing="1rem",
            width="100%"
        )
        for _ in range(5)
    ],
    spacing="1rem",
    width="100%"
)

Conditional Loading

class State(rx.State):
    is_loading: bool = True
    data: str = ""

    async def load_data(self):
        self.is_loading = True
        yield
        # Simulate API call
        await asyncio.sleep(2)
        self.data = "Loaded content"
        self.is_loading = False

rx.cond(
    State.is_loading,
    ui.skeleton(class_name="h-20 w-full rounded-lg"),
    rx.box(State.data, padding="1rem", border="1px solid gray")
)

Props Reference

class_name
str
CSS classes for customizing size, shape, and other styles

Styling

From source code at reflex_ui/components/base/skeleton.py:10-13:
  • Base class: animate-pulse bg-secondary-6
  • Uses Tailwind’s pulse animation
  • Background color from the secondary color scale
  • Inherits size and shape from class_name prop

Implementation Details

From source code at reflex_ui/components/base/skeleton.py:16-24:
  • Simple Div component with memoization
  • Lightweight with minimal overhead
  • No JavaScript required
  • Pure CSS animations
  • Fully customizable through Tailwind classes

Build docs developers (and LLMs) love