# Hover card: Loading content

> Start fetching in `onOpenChange` and show a skeleton until the data arrives. When the content changes, the card eases to its new height instead of jumping.

Example: https://hextaui.com/docs/hover-card/examples/async
Component docs: https://hextaui.com/docs/hover-card.md

## Add this example

```bash
npx shadcn@latest add https://hextaui.com/r/hover-card-async.json
```

This adds `components/examples/hover-card/async.tsx` with the Hover card component and the HextaUI theme tokens.

## Source

```tsx title="components/examples/hover-card/async.tsx"
"use client"

import * as React from "react"

import {
  HoverCard,
  HoverCardContent,
  HoverCardTrigger,
} from "@/components/ui/hover-card"
import { Skeleton, SkeletonText } from "@/components/ui/skeleton"

type Repo = { name: string; description: string; stars: number }

function fetchRepo(): Promise<Repo> {
  return new Promise((resolve) =>
    setTimeout(
      () =>
        resolve({
          name: "hextaui/hextaui",
          description:
            "Components built on shadcn/ui and Base UI, with motion, keyboard support and edge cases handled. Copy them into your project and make them yours.",
          stars: 2140,
        }),
      900
    )
  )
}

export function HoverCardAsync() {
  const [repo, setRepo] = React.useState<Repo | null>(null)
  const request = React.useRef<Promise<void> | null>(null)

  return (
    <HoverCard
      onOpenChange={(open) => {
        if (open && !request.current) {
          request.current = fetchRepo().then(setRepo)
        }
      }}
    >
      <HoverCardTrigger
        href="#"
        delay={200}
        render={
          <a className="text-sm font-medium underline decoration-border underline-offset-4 hover:decoration-foreground" />
        }
      >
        hextaui/hextaui
      </HoverCardTrigger>
      <HoverCardContent className="w-72" aria-busy={!repo}>
        {repo ? (
          <div className="flex flex-col gap-1.5">
            <p className="font-medium">{repo.name}</p>
            <p className="text-muted-foreground">{repo.description}</p>
            <p className="text-xs text-muted-foreground">
              {repo.stars.toLocaleString("en-US")} stars
            </p>
          </div>
        ) : (
          <div className="flex flex-col gap-2">
            <Skeleton className="h-4 w-32" />
            <SkeletonText lines={2} />
          </div>
        )}
      </HoverCardContent>
    </HoverCard>
  )
}
```

## Props in this example

### HoverCard

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `onOpenChange` | `(open: boolean, details) => void` | – | details.reason is trigger-hover, trigger-focus, trigger-press, outside-press, escape-key, imperative-action or none. |

### HoverCardTrigger

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `href` | `string` | – |  |
| `delay` | `number` | `600` | Milliseconds before hover or focus opens the card. |
| `render` | `ReactElement \| (props, state) => ReactElement` | `<a>` | Render your own link, such as <Button variant="link" /> or a router link. |

## More Hover card examples

- [Side](https://hextaui.com/docs/hover-card/examples/sides.md)
- [Delay](https://hextaui.com/docs/hover-card/examples/delay.md)
- [Inline link](https://hextaui.com/docs/hover-card/examples/inline.md)
- [Interactive content](https://hextaui.com/docs/hover-card/examples/rich-content.md)
- [Shared card](https://hextaui.com/docs/hover-card/examples/detached.md)
- [Arrow](https://hextaui.com/docs/hover-card/examples/arrow.md)
- [Controlled](https://hextaui.com/docs/hover-card/examples/controlled.md)
- [Long content](https://hextaui.com/docs/hover-card/examples/long-content.md)
- [Right to left](https://hextaui.com/docs/hover-card/examples/rtl.md)
