# 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