PageCardPRO
Usage
The PageCard component provides a flexible way to display content in a card with an illustration in the default slot.
Title
Use the title
prop to set the title of the card.
<template>
<UPageCard title="Tailwind CSS" />
</template>
Description
Use the description
prop to set the description of the card.
<template>
<UPageCard
title="Tailwind CSS"
description="Nuxt UI v3 integrates with latest Tailwind CSS v4, bringing significant improvements."
/>
</template>
Icon
Use the icon
prop to set the icon of the card.
<template>
<UPageCard
title="Tailwind CSS"
description="Nuxt UI v3 integrates with latest Tailwind CSS v4, bringing significant improvements."
icon="i-simple-icons-tailwindcss"
/>
</template>
Link
You can pass any property from the <NuxtLink>
component such as to
, target
, rel
, etc.
<template>
<UPageCard
title="Tailwind CSS"
description="Nuxt UI v3 integrates with latest Tailwind CSS v4, 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.
<template>
<UPageCard
title="Tailwind CSS"
description="Nuxt UI v3 integrates with latest Tailwind CSS v4, bringing significant improvements."
icon="i-simple-icons-tailwindcss"
to="https://tailwindcss.com/docs/v4-beta"
target="_blank"
variant="soft"
/>
</template>
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
.
<template>
<UPageCard
title="Tailwind CSS"
description="Nuxt UI v3 integrates with latest Tailwind CSS v4, 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.
<template>
<UPageCard
title="Tailwind CSS"
description="Nuxt UI v3 integrates with latest Tailwind CSS v4, bringing significant improvements."
icon="i-simple-icons-tailwindcss"
orientation="horizontal"
reverse
>
<img src="/tailwindcss-v4.svg" alt="Tailwind CSS" class="w-full" />
</UPageCard>
</template>
Highlight
Use the highlight
and highlight-color
props to display a highlighted border around the card.
<template>
<UPageCard
title="Tailwind CSS"
description="Nuxt UI v3 integrates with latest Tailwind CSS v4, bringing significant improvements."
icon="i-simple-icons-tailwindcss"
orientation="horizontal"
highlight
highlight-color="primary"
>
<img src="/tailwindcss-v4.svg" alt="Tailwind CSS" class="w-full" />
</UPageCard>
</template>
Spotlight
Use the spotlight
and spotlight-color
props to display a spotlight effect that follows your mouse cursor and highlights borders on hover.
to
prop. It's best to use it with the outline
variant.<template>
<UPageCard
title="Tailwind CSS"
description="Nuxt UI v3 integrates with latest Tailwind CSS v4, bringing significant improvements."
icon="i-simple-icons-tailwindcss"
orientation="horizontal"
spotlight
spotlight-color="primary"
>
<img src="/tailwindcss-v4.svg" alt="Tailwind CSS" class="w-full" />
</UPageCard>
</template>
--spotlight-color
and --spotlight-size
CSS variables:<template>
<UPageCard spotlight class="[--spotlight-color:var(--ui-error)] [--spotlight-size:200px]" />
</template>
Examples
As a testimonial
Use the User component in the header
or footer
slot to make the card look like a testimonial.
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>
API
Props
Prop | Default | Type |
---|---|---|
as |
|
The element or component this component should render as. |
icon |
The icon displayed above the title. | |
title |
| |
description |
| |
orientation |
|
The orientation of the page card. |
reverse |
|
Reverse the order of the default slot. |
highlight |
Display a line around the page card. | |
highlightColor |
|
|
spotlight |
Display a spotlight effect that follows your mouse cursor and highlights borders on hover. | |
spotlightColor |
|
|
variant |
|
|
to |
| |
target |
| |
ui |
|
Slots
Slot | Type |
---|---|
header |
|
body |
|
leading |
|
title |
|
description |
|
footer |
|
default |
|
Theme
export default defineAppConfig({
uiPro: {
pageCard: {
slots: {
root: 'relative flex rounded-[calc(var(--ui-radius)*2)]',
spotlight: 'absolute inset-0 rounded-[inherit] pointer-events-none bg-(--ui-bg)/90',
container: 'relative 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-(--ui-primary)',
title: 'text-base text-pretty font-semibold text-(--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-(--ui-bg-inverted) text-(--ui-bg)',
title: 'text-(--ui-bg)',
description: 'text-(--ui-text-dimmed)'
},
outline: {
root: 'bg-(--ui-bg) ring ring-(--ui-border)',
description: 'text-(--ui-text-muted)'
},
soft: {
root: 'bg-(--ui-bg-elevated)/50',
description: 'text-(--ui-text-toned)'
},
subtle: {
root: 'bg-(--ui-bg-elevated)/50 ring ring-(--ui-border)',
description: 'text-(--ui-text-toned)'
},
ghost: {
description: 'text-(--ui-text-muted)'
},
naked: {
container: 'p-0 sm:p-0',
description: 'text-(--ui-text-muted)'
}
},
to: {
true: {
root: [
'transition'
]
}
},
title: {
true: {
description: 'mt-1'
}
},
highlight: {
true: {
root: 'ring-2'
}
},
highlightColor: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
},
spotlight: {
true: {
root: '[--spotlight-size:400px] before:absolute before:-inset-px before:pointer-events-none before:rounded-[inherit] before:bg-[radial-gradient(var(--spotlight-size)_var(--spotlight-size)_at_calc(var(--spotlight-x,0px))_calc(var(--spotlight-y,0px)),var(--spotlight-color),transparent_70%)]'
}
},
spotlightColor: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
}
},
compoundVariants: [
{
variant: 'solid',
to: true,
class: {
root: 'hover:bg-(--ui-bg-inverted)/90'
}
},
{
variant: 'outline',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)/50'
}
},
{
variant: 'soft',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)'
}
},
{
variant: 'subtle',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)'
}
},
{
variant: 'subtle',
to: true,
highlight: false,
class: {
root: 'hover:ring-(--ui-border-accented)'
}
},
{
variant: 'ghost',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)/50'
}
},
{
highlightColor: 'primary',
highlight: true,
class: {
root: 'ring-(--ui-primary)'
}
},
{
highlightColor: 'neutral',
highlight: true,
class: {
root: 'ring-(--ui-border-inverted)'
}
},
{
spotlightColor: 'primary',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-primary)]'
}
},
{
spotlightColor: 'secondary',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-secondary)]'
}
},
{
spotlightColor: 'success',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-success)]'
}
},
{
spotlightColor: 'info',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-info)]'
}
},
{
spotlightColor: 'warning',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-warning)]'
}
},
{
spotlightColor: 'error',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-error)]'
}
},
{
spotlightColor: 'neutral',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-bg-inverted)]'
}
}
],
defaultVariants: {
variant: 'outline',
highlightColor: 'primary',
spotlightColor: 'primary'
}
}
}
})
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)]',
spotlight: 'absolute inset-0 rounded-[inherit] pointer-events-none bg-(--ui-bg)/90',
container: 'relative 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-(--ui-primary)',
title: 'text-base text-pretty font-semibold text-(--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-(--ui-bg-inverted) text-(--ui-bg)',
title: 'text-(--ui-bg)',
description: 'text-(--ui-text-dimmed)'
},
outline: {
root: 'bg-(--ui-bg) ring ring-(--ui-border)',
description: 'text-(--ui-text-muted)'
},
soft: {
root: 'bg-(--ui-bg-elevated)/50',
description: 'text-(--ui-text-toned)'
},
subtle: {
root: 'bg-(--ui-bg-elevated)/50 ring ring-(--ui-border)',
description: 'text-(--ui-text-toned)'
},
ghost: {
description: 'text-(--ui-text-muted)'
},
naked: {
container: 'p-0 sm:p-0',
description: 'text-(--ui-text-muted)'
}
},
to: {
true: {
root: [
'transition'
]
}
},
title: {
true: {
description: 'mt-1'
}
},
highlight: {
true: {
root: 'ring-2'
}
},
highlightColor: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
},
spotlight: {
true: {
root: '[--spotlight-size:400px] before:absolute before:-inset-px before:pointer-events-none before:rounded-[inherit] before:bg-[radial-gradient(var(--spotlight-size)_var(--spotlight-size)_at_calc(var(--spotlight-x,0px))_calc(var(--spotlight-y,0px)),var(--spotlight-color),transparent_70%)]'
}
},
spotlightColor: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
}
},
compoundVariants: [
{
variant: 'solid',
to: true,
class: {
root: 'hover:bg-(--ui-bg-inverted)/90'
}
},
{
variant: 'outline',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)/50'
}
},
{
variant: 'soft',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)'
}
},
{
variant: 'subtle',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)'
}
},
{
variant: 'subtle',
to: true,
highlight: false,
class: {
root: 'hover:ring-(--ui-border-accented)'
}
},
{
variant: 'ghost',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)/50'
}
},
{
highlightColor: 'primary',
highlight: true,
class: {
root: 'ring-(--ui-primary)'
}
},
{
highlightColor: 'neutral',
highlight: true,
class: {
root: 'ring-(--ui-border-inverted)'
}
},
{
spotlightColor: 'primary',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-primary)]'
}
},
{
spotlightColor: 'secondary',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-secondary)]'
}
},
{
spotlightColor: 'success',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-success)]'
}
},
{
spotlightColor: 'info',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-info)]'
}
},
{
spotlightColor: 'warning',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-warning)]'
}
},
{
spotlightColor: 'error',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-error)]'
}
},
{
spotlightColor: 'neutral',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-bg-inverted)]'
}
}
],
defaultVariants: {
variant: 'outline',
highlightColor: 'primary',
spotlightColor: 'primary'
}
}
}
})
]
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'
export default defineConfig({
plugins: [
vue(),
uiPro({
uiPro: {
pageCard: {
slots: {
root: 'relative flex rounded-[calc(var(--ui-radius)*2)]',
spotlight: 'absolute inset-0 rounded-[inherit] pointer-events-none bg-(--ui-bg)/90',
container: 'relative 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-(--ui-primary)',
title: 'text-base text-pretty font-semibold text-(--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-(--ui-bg-inverted) text-(--ui-bg)',
title: 'text-(--ui-bg)',
description: 'text-(--ui-text-dimmed)'
},
outline: {
root: 'bg-(--ui-bg) ring ring-(--ui-border)',
description: 'text-(--ui-text-muted)'
},
soft: {
root: 'bg-(--ui-bg-elevated)/50',
description: 'text-(--ui-text-toned)'
},
subtle: {
root: 'bg-(--ui-bg-elevated)/50 ring ring-(--ui-border)',
description: 'text-(--ui-text-toned)'
},
ghost: {
description: 'text-(--ui-text-muted)'
},
naked: {
container: 'p-0 sm:p-0',
description: 'text-(--ui-text-muted)'
}
},
to: {
true: {
root: [
'transition'
]
}
},
title: {
true: {
description: 'mt-1'
}
},
highlight: {
true: {
root: 'ring-2'
}
},
highlightColor: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
},
spotlight: {
true: {
root: '[--spotlight-size:400px] before:absolute before:-inset-px before:pointer-events-none before:rounded-[inherit] before:bg-[radial-gradient(var(--spotlight-size)_var(--spotlight-size)_at_calc(var(--spotlight-x,0px))_calc(var(--spotlight-y,0px)),var(--spotlight-color),transparent_70%)]'
}
},
spotlightColor: {
primary: '',
secondary: '',
success: '',
info: '',
warning: '',
error: '',
neutral: ''
}
},
compoundVariants: [
{
variant: 'solid',
to: true,
class: {
root: 'hover:bg-(--ui-bg-inverted)/90'
}
},
{
variant: 'outline',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)/50'
}
},
{
variant: 'soft',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)'
}
},
{
variant: 'subtle',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)'
}
},
{
variant: 'subtle',
to: true,
highlight: false,
class: {
root: 'hover:ring-(--ui-border-accented)'
}
},
{
variant: 'ghost',
to: true,
class: {
root: 'hover:bg-(--ui-bg-elevated)/50'
}
},
{
highlightColor: 'primary',
highlight: true,
class: {
root: 'ring-(--ui-primary)'
}
},
{
highlightColor: 'neutral',
highlight: true,
class: {
root: 'ring-(--ui-border-inverted)'
}
},
{
spotlightColor: 'primary',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-primary)]'
}
},
{
spotlightColor: 'secondary',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-secondary)]'
}
},
{
spotlightColor: 'success',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-success)]'
}
},
{
spotlightColor: 'info',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-info)]'
}
},
{
spotlightColor: 'warning',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-warning)]'
}
},
{
spotlightColor: 'error',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-error)]'
}
},
{
spotlightColor: 'neutral',
spotlight: true,
class: {
root: '[--spotlight-color:var(--ui-bg-inverted)]'
}
}
],
defaultVariants: {
variant: 'outline',
highlightColor: 'primary',
spotlightColor: 'primary'
}
}
}
})
]
})