Render an empty state using the Empty
component.
1import { ArrowUpRightIcon, FilePen } from 'lucide-react'
2
3import { Button } from '@/components/ui/button'
4import {
5 Empty,
6 EmptyContent,
7 EmptyDescription,
8 EmptyHeader,
9 EmptyMedia,
10 EmptyTitle,
11} from '@/components/ui/empty'
12
13export function EmptyDemo() {
14 return (
15 <Empty>
16 <EmptyHeader>
17 <EmptyMedia variant="icon">
18 <FilePen />
19 </EmptyMedia>
20 <EmptyTitle>No Tasks Yet</EmptyTitle>
21 <EmptyDescription>
22 You haven't added any tasks. Start work by creating a
23 new task or importing one.
24 </EmptyDescription>
25 </EmptyHeader>
26 <EmptyContent>
27 <div className="flex gap-2">
28 <Button>Create Task</Button>
29 <Button variant="outline">Import Task</Button>
30 </div>
31 </EmptyContent>
32 <Button
33 variant="link"
34 asChild
35 className="text-muted-foreground"
36 size="sm"
37 >
38 <a href="#">
39 Learn how it works <ArrowUpRightIcon />
40 </a>
41 </Button>
42 </Empty>
43 )
44}
45
Install the following dependencies:
Combine the empty state with a skeleton or spinner to indicate data loading before content appears.
1import { UserRound } from 'lucide-react'
2
3import {
4 Empty,
5 EmptyContent,
6 EmptyDescription,
7 EmptyHeader,
8 EmptyMedia,
9 EmptyTitle,
10} from '@/components/ui/empty'
11import { Skeleton } from '@/components/ui/skeleton'
12
13export function EmptyLoading() {
14 return (
15 <Empty>
16 <EmptyHeader>
17 <EmptyMedia variant="icon">
18 <Skeleton className="grid size-10 place-content-center rounded-full">
19 <UserRound className="size-6 text-gray-500" />
20 </Skeleton>
21 </EmptyMedia>
22 <EmptyTitle>Fetching Your Profile</EmptyTitle>
23 <EmptyDescription>
24 Please wait while we fetch your profile. This won't
25 take long.
26 </EmptyDescription>
27 </EmptyHeader>
28 <EmptyContent>
29 <div className="flex w-full flex-col gap-3">
30 <Skeleton className="h-4 w-[calc(100%-30%)] mx-auto" />
31 <div className="flex flex-col gap-1.5">
32 <Skeleton className="h-2.5 w-full" />
33 <Skeleton className="h-2.5 w-full" />
34 <Skeleton className="h-2.5 w-full" />
35 </div>
36
37 <div className="mt-2 flex items-center gap-2 mx-auto">
38 <Skeleton className="h-2.5 w-16 rounded" />
39 <Skeleton className="h-2.5 w-16 rounded" />
40 </div>
41 </div>
42 </EmptyContent>
43 </Empty>
44 )
45}
46
Apply the bg-*
and bg-gradient-*
utilities to give the empty state a background.
1import { MessageCircleIcon, MessageSquareMore } from 'lucide-react'
2
3import { Button } from '@/components/ui/button'
4import {
5 Empty,
6 EmptyContent,
7 EmptyDescription,
8 EmptyHeader,
9 EmptyMedia,
10 EmptyTitle,
11} from '@/components/ui/empty'
12
13export function EmptyMuted() {
14 return (
15 <Empty className="from-gray-100/80 to-gray/10 h-full bg-gradient-to-t from-30%">
16 <EmptyHeader>
17 <EmptyMedia variant="icon">
18 <MessageSquareMore />
19 </EmptyMedia>
20 <EmptyTitle>No Messages</EmptyTitle>
21 <EmptyDescription>
22 Start a conversation to see your messages here.
23 </EmptyDescription>
24 </EmptyHeader>
25 <EmptyContent>
26 <Button variant="outline" size="sm">
27 <MessageCircleIcon />
28 New Message
29 </Button>
30 </EmptyContent>
31 </Empty>
32 )
33}
34
Use the EmptyMedia
component to showcase an avatar within the empty state.
1import {
2 Avatar,
3 AvatarFallback,
4 AvatarImage,
5} from '@/components/ui/avatar'
6import { Button } from '@/components/ui/button'
7import {
8 Empty,
9 EmptyContent,
10 EmptyDescription,
11 EmptyHeader,
12 EmptyMedia,
13 EmptyTitle,
14} from '@/components/ui/empty'
15
16export function EmptyAvatar() {
17 return (
18 <Empty>
19 <EmptyHeader>
20 <EmptyMedia variant="default">
21 <Avatar className="size-12">
22 <AvatarImage
23 src="/images/profile8.png"
24 className="grayscale"
25 />
26 <AvatarFallback>CP</AvatarFallback>
27 </Avatar>
28 </EmptyMedia>
29 <EmptyTitle>No Customer Profile</EmptyTitle>
30 <EmptyDescription>
31 You haven't added any customer profiles yet. Create one
32 to start managing your client information easily.
33 </EmptyDescription>
34 </EmptyHeader>
35 <EmptyContent>
36 <Button size="sm">Add Customer</Button>
37 </EmptyContent>
38 </Empty>
39 )
40}
41
Use the EmptyMedia
component to display multiple avatars representing users, teams, or collaborators within the empty state.
1import {
2 Avatar,
3 AvatarFallback,
4 AvatarImage,
5} from '@/components/ui/avatar'
6import { Button } from '@/components/ui/button'
7import {
8 Empty,
9 EmptyContent,
10 EmptyDescription,
11 EmptyHeader,
12 EmptyMedia,
13 EmptyTitle,
14} from '@/components/ui/empty'
15
16export function EmptyMultipleAvatars() {
17 return (
18 <Empty>
19 <EmptyHeader>
20 <EmptyMedia variant="default" className="flex -space-x-3">
21 <Avatar className="border-2" variant={'outline'} >
22 <AvatarImage src="/images/profile1.png" />
23 <AvatarFallback>JS</AvatarFallback>
24 </Avatar>
25 <Avatar className="border-2" variant={'outline'} >
26 <AvatarImage src="/images/profile2.png" />
27 <AvatarFallback>AL</AvatarFallback>
28 </Avatar>
29 <Avatar className="border-2" variant={'outline'} >
30 <AvatarImage src="/images/profile3.png" />
31 <AvatarFallback>MK</AvatarFallback>
32 </Avatar>
33 <Avatar className="border-2" variant={'outline'} >
34 <AvatarImage src="/images/profile4.png" />
35 <AvatarFallback>PW</AvatarFallback>
36 </Avatar>
37 </EmptyMedia>
38 <EmptyTitle>No Active Collaborations</EmptyTitle>
39 <EmptyDescription>
40 Your team hasn't started any projects yet. Create one
41 to begin collaborating together.
42 </EmptyDescription>
43 </EmptyHeader>
44 <EmptyContent>
45 <Button size="sm">Create Project</Button>
46 </EmptyContent>
47 </Empty>
48 )
49}
50
Enhance the empty state by adding an outline with the border utility class.
1import { ShoppingCart } from 'lucide-react'
2
3import { Button } from '@/components/ui/button'
4import {
5 Empty,
6 EmptyContent,
7 EmptyDescription,
8 EmptyHeader,
9 EmptyMedia,
10 EmptyTitle,
11} from '@/components/ui/empty'
12
13export function EmptyOutline() {
14 return (
15 <Empty className="border-2 border-gray-400 border-dotted">
16 <EmptyHeader>
17 <EmptyMedia variant="icon">
18 <ShoppingCart />
19 </EmptyMedia>
20 <EmptyTitle>No Orders Found</EmptyTitle>
21 <EmptyDescription>
22 You don't have any orders yet. Start shopping to create
23 your first order.
24 </EmptyDescription>
25 </EmptyHeader>
26 <EmptyContent>
27 <Button variant="outline" size="sm">
28 Browse Products
29 </Button>
30 </EmptyContent>
31 </Empty>
32 )
33}
34
The core component for the empty state, used to enclose EmptyHeader
and EmptyContent
.
Prop | Type | Default |
---|---|---|
className | string | - |
The EmptyMedia
component displays the visual element of an empty state, such as an icon, image, or avatar.
Prop | Type | Default |
---|---|---|
variant | default ,icon | default |
className | string | - |