PageCard

A pre-styled card component that displays a title, description and optional link.

Usage

The PageCard component provides a flexible way to display content in a card with an illustration in the default slot.

Tailwind CSS
Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements.
Tailwind CSS
Use the PageGrid, PageColumns or PageList components to display multiple PageCard.

Title

Use the title prop to set the title of the card.

Tailwind CSS
<template>
  <UPageCard title="Tailwind CSS" />
</template>

Description

Use the description prop to set the description of the card.

Tailwind CSS
Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements.
<template>
  <UPageCard
    title="Tailwind CSS"
    description="Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements."
  />
</template>

Icon

Use the icon prop to set the icon of the card.

Tailwind CSS
Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements.
<template>
  <UPageCard
    title="Tailwind CSS"
    description="Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements."
    icon="i-simple-icons-tailwindcss"
  />
</template>

Highlight

Use the highlight prop to display a highlighted border around the card.

Tailwind CSS
Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements.
<template>
  <UPageCard
    title="Tailwind CSS"
    description="Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements."
    icon="i-simple-icons-tailwindcss"
    highlight
  />
</template>

You can pass any property from the <NuxtLink> component such as to, target, rel, etc.

Tailwind CSS
Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements.
<template>
  <UPageCard
    title="Tailwind CSS"
    description="Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements."
    icon="i-simple-icons-tailwindcss"
    to="https://tailwindcss.com/docs/v4-beta"
    target="_blank"
  />
</template>

Variant

Use the variant prop to change the style of the card.

Tailwind CSS
Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements.
<template>
  <UPageCard
    title="Tailwind CSS"
    description="Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements."
    icon="i-simple-icons-tailwindcss"
    to="https://tailwindcss.com/docs/v4-beta"
    target="_blank"
    variant="soft"
  />
</template>
You can apply the light or dark class to the links slot when using the solid variant to reverse the colors.

Orientation

Use the orientation prop to change the orientation with the default slot. Defaults to vertical.

Tailwind CSS
Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements.
Tailwind CSS
<template>
  <UPageCard
    title="Tailwind CSS"
    description="Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements."
    icon="i-simple-icons-tailwindcss"
    orientation="horizontal"
  >
    <img src="/tailwindcss-v4.svg" alt="Tailwind CSS" class="w-full" />
  </UPageCard>
</template>

Reverse

Use the reverse prop to reverse the orientation of the default slot.

Tailwind CSS
Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements.
Tailwind CSS
<template>
  <UPageCard
    title="Tailwind CSS"
    description="Nuxt UI v3 integrates with latest Tailwind CSS v4 beta, bringing significant improvements."
    icon="i-simple-icons-tailwindcss"
    orientation="horizontal"
    reverse
  >
    <img src="/tailwindcss-v4.svg" alt="Tailwind CSS" class="w-full" />
  </UPageCard>
</template>

Examples

As a testimonial

Use the User component in the header or footer slot to make the card look like a testimonial.

“Nuxt on Cloudflare infra with minimal effort - this is huge!”
EY

Evan You

Author of Vue.js and Vite

<script setup lang="ts">
const testimonial = ref({
  user: {
    name: 'Evan You',
    description: 'Author of Vue.js and Vite',
    avatar: {
      src: 'https://avatars.githubusercontent.com/u/499550?v=4',
      alt: 'Evan You'
    }
  },
  quote: '“Nuxt on Cloudflare infra with minimal effort - this is huge!”'
})
</script>

<template>
  <UPageCard :description="testimonial.quote" class="w-60">
    <template #footer>
      <UUser v-bind="testimonial.user" />
    </template>
  </UPageCard>
</template>
You can use the PageColumns component to display multiple PageCard in a multi-column layout.

API

Props

Prop Default Type
as

'div'

any

The element or component this component should render as.

icon

string

title

string

description

string

orientation

'vertical'

"horizontal" | "vertical"

The orientation of the page card.

reverse

false

boolean

Reverse the order of the default slot.

highlight

boolean

Display a line around the page card.

variant

'outline'

"solid" | "outline" | "soft" | "subtle" | "ghost" | "naked"

to

string | RouteLocationAsRelativeGeneric | RouteLocationAsPathGeneric

target

null | "_blank" | "_parent" | "_self" | "_top" | string & {}

ui

Partial<{ root: string; container: string; wrapper: string; header: string; body: string; footer: string; leading: string; leadingIcon: string; title: string; description: string; }>

Slots

Slot Type
header

{}

body

{}

leading

{}

title

{}

description

{}

footer

{}

default

{}

Theme

app.config.ts
export default defineAppConfig({
  uiPro: {
    pageCard: {
      slots: {
        root: 'relative flex rounded-[calc(var(--ui-radius)*2)]',
        container: 'flex flex-col flex-1 lg:grid gap-x-8 gap-y-4 p-4 sm:p-6',
        wrapper: '',
        header: 'mb-4',
        body: '',
        footer: 'mt-4',
        leading: 'inline-flex items-center justify-center mb-2.5',
        leadingIcon: 'size-5 shrink-0 text-[var(--ui-primary)]',
        title: 'text-base text-pretty font-semibold text-[var(--ui-text-highlighted)]',
        description: 'text-[15px] text-pretty'
      },
      variants: {
        orientation: {
          horizontal: {
            container: 'lg:grid-cols-2 lg:items-center'
          },
          vertical: {
            container: ''
          }
        },
        reverse: {
          true: {
            wrapper: 'lg:order-last'
          }
        },
        variant: {
          solid: {
            root: 'bg-[var(--ui-bg-inverted)] text-[var(--ui-bg)]',
            title: 'text-[var(--ui-bg)]',
            description: 'text-[var(--ui-text-dimmed)]'
          },
          outline: {
            root: 'bg-[var(--ui-bg)] ring ring-[var(--ui-border)]',
            description: 'text-[var(--ui-text-muted)]'
          },
          soft: {
            root: 'bg-[var(--ui-bg-elevated)]/50',
            description: 'text-[var(--ui-text-toned)]'
          },
          subtle: {
            root: 'bg-[var(--ui-bg-elevated)]/50 ring ring-[var(--ui-border)]',
            description: 'text-[var(--ui-text-toned)]'
          },
          ghost: {
            description: 'text-[var(--ui-text-muted)]'
          },
          naked: {
            container: 'p-0 sm:p-0',
            description: 'text-[var(--ui-text-muted)]'
          }
        },
        to: {
          true: {
            root: [
              'transition'
            ]
          }
        },
        title: {
          true: {
            description: 'mt-1'
          }
        },
        highlight: {
          true: {
            root: 'ring-2 ring-[var(--ui-primary)]'
          }
        }
      },
      compoundVariants: [
        {
          variant: 'solid',
          to: true,
          class: {
            root: 'hover:bg-[var(--ui-bg-inverted)]/90'
          }
        },
        {
          variant: 'outline',
          to: true,
          class: {
            root: 'hover:bg-[var(--ui-bg-elevated)]/50'
          }
        },
        {
          variant: 'soft',
          to: true,
          class: {
            root: 'hover:bg-[var(--ui-bg-elevated)]'
          }
        },
        {
          variant: 'subtle',
          to: true,
          class: {
            root: 'hover:bg-[var(--ui-bg-elevated)]'
          }
        },
        {
          variant: 'subtle',
          to: true,
          highlight: false,
          class: {
            root: 'hover:ring-[var(--ui-border-accented)]'
          }
        },
        {
          variant: 'ghost',
          to: true,
          class: {
            root: 'hover:bg-[var(--ui-bg-elevated)]/50'
          }
        }
      ],
      defaultVariants: {
        variant: 'outline'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      uiPro: {
        pageCard: {
          slots: {
            root: 'relative flex rounded-[calc(var(--ui-radius)*2)]',
            container: 'flex flex-col flex-1 lg:grid gap-x-8 gap-y-4 p-4 sm:p-6',
            wrapper: '',
            header: 'mb-4',
            body: '',
            footer: 'mt-4',
            leading: 'inline-flex items-center justify-center mb-2.5',
            leadingIcon: 'size-5 shrink-0 text-[var(--ui-primary)]',
            title: 'text-base text-pretty font-semibold text-[var(--ui-text-highlighted)]',
            description: 'text-[15px] text-pretty'
          },
          variants: {
            orientation: {
              horizontal: {
                container: 'lg:grid-cols-2 lg:items-center'
              },
              vertical: {
                container: ''
              }
            },
            reverse: {
              true: {
                wrapper: 'lg:order-last'
              }
            },
            variant: {
              solid: {
                root: 'bg-[var(--ui-bg-inverted)] text-[var(--ui-bg)]',
                title: 'text-[var(--ui-bg)]',
                description: 'text-[var(--ui-text-dimmed)]'
              },
              outline: {
                root: 'bg-[var(--ui-bg)] ring ring-[var(--ui-border)]',
                description: 'text-[var(--ui-text-muted)]'
              },
              soft: {
                root: 'bg-[var(--ui-bg-elevated)]/50',
                description: 'text-[var(--ui-text-toned)]'
              },
              subtle: {
                root: 'bg-[var(--ui-bg-elevated)]/50 ring ring-[var(--ui-border)]',
                description: 'text-[var(--ui-text-toned)]'
              },
              ghost: {
                description: 'text-[var(--ui-text-muted)]'
              },
              naked: {
                container: 'p-0 sm:p-0',
                description: 'text-[var(--ui-text-muted)]'
              }
            },
            to: {
              true: {
                root: [
                  'transition'
                ]
              }
            },
            title: {
              true: {
                description: 'mt-1'
              }
            },
            highlight: {
              true: {
                root: 'ring-2 ring-[var(--ui-primary)]'
              }
            }
          },
          compoundVariants: [
            {
              variant: 'solid',
              to: true,
              class: {
                root: 'hover:bg-[var(--ui-bg-inverted)]/90'
              }
            },
            {
              variant: 'outline',
              to: true,
              class: {
                root: 'hover:bg-[var(--ui-bg-elevated)]/50'
              }
            },
            {
              variant: 'soft',
              to: true,
              class: {
                root: 'hover:bg-[var(--ui-bg-elevated)]'
              }
            },
            {
              variant: 'subtle',
              to: true,
              class: {
                root: 'hover:bg-[var(--ui-bg-elevated)]'
              }
            },
            {
              variant: 'subtle',
              to: true,
              highlight: false,
              class: {
                root: 'hover:ring-[var(--ui-border-accented)]'
              }
            },
            {
              variant: 'ghost',
              to: true,
              class: {
                root: 'hover:bg-[var(--ui-bg-elevated)]/50'
              }
            }
          ],
          defaultVariants: {
            variant: 'outline'
          }
        }
      }
    })
  ]
})