# Skeleton **Category**: react **URL**: https://www.heroui.com/docs/react/migration/skeleton **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/migration/(components)/skeleton.mdx > Migration guide for Skeleton from HeroUI v2 to v3 *** Refer to the [v3 Skeleton documentation](/docs/react/components/skeleton) for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2. ## Structure Changes In v2, Skeleton wrapped children and showed/hid them based on `isLoaded`: ```tsx import { Skeleton } from "@heroui/react"; export default function App() { const isLoaded = false; return (
); } ``` In v3, Skeleton is a standalone placeholder that you control visibility of manually: ```tsx import { Skeleton } from "@heroui/react"; export default function App() { const isLoaded = false; return ( <> {!isLoaded ? ( ) : (
)} ); } ``` ## Key Changes ### 1. Component Behavior **v2:** Wrapped children and showed/hid them based on `isLoaded` **v3:** Standalone placeholder - you control visibility manually ### 2. Prop Changes | v2 Prop | v3 Location | Notes | |---------|-------------|-------| | `isLoaded` | — | Control visibility manually with conditional rendering | | `disableAnimation` | `animationType` | Use `animationType="shimmer" \| "pulse" \| "none"` (use `"none"` to disable) | | `classNames` | — | Use `className` prop directly | | `children` | — | Skeleton no longer wraps content | ### 3. New Props - `animationType` - Controls animation type: `"shimmer"` (default), `"pulse"`, or `"none"` ## Migration Examples ### With Loaded State ```tsx import { useState } from "react"; const [isLoaded, setIsLoaded] = useState(false);
``` ```tsx import { useState } from "react"; const [isLoaded, setIsLoaded] = useState(false); {!isLoaded ? ( ) : (
)} ``` ### Standalone Skeleton ```tsx
```
```tsx
```
### Animation Types ```tsx {/* Shimmer (default) */}
{/* No animation */}
``` ```tsx {/* Shimmer (default) */} {/* Pulse */} {/* No animation */} ``` ### Complex Example: Card with Content ```tsx import { useState } from "react"; const [isLoaded, setIsLoaded] = useState(false);
``` ```tsx import { useState } from "react"; const [isLoaded, setIsLoaded] = useState(false); {!isLoaded ? ( <>
) : ( <>
)} ``` ### Synchronized Shimmer Effect In v3, you can create a synchronized shimmer that passes over all skeleton elements at once. Apply the `skeleton--shimmer` class to a parent container and set `animationType="none"` on each child Skeleton: ```tsx {/* The parent container drives a single shimmer across all children */}
``` This is useful for card-like layouts where you want a single, unified shimmer sweep instead of each skeleton animating independently. ## Global Animation Configuration In v3, you can set a default animation type globally using CSS variables: ```css :root { --skeleton-animation: pulse; /* shimmer, pulse, or none */ } ``` This can be overridden by the `animationType` prop on individual components. ## Summary 1. **No Children Wrapping**: Skeleton no longer wraps children - it's a standalone placeholder 2. **No `isLoaded` Prop**: Control visibility manually with conditional rendering 3. **Animation Control**: `disableAnimation` → `animationType` (`"shimmer"`, `"pulse"`, `"none"`) 4. **Styling**: `classNames` → `className` prop directly 5. **Simplified API**: Much simpler component focused on being a placeholder 6. **Synchronized Shimmer**: Use `skeleton--shimmer` class on a parent container with `animationType="none"` on children for a unified shimmer sweep