BlogPost

A customizable article to display in a blog page.

Usage

The BlogPost component provides a flexible way to display a blog post or article with customizable content including title, description, image, etc.

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
 

Anthony Fu

antfu7

Use the BlogPosts component to display multiple blog posts in a responsive grid layout.

Title

Use the title prop to display the title of the BlogPost.

Introducing Nuxt Icon v1

<template>
  <UBlogPost title="Introducing Nuxt Icon v1" />
</template>

Description

Use the description prop to display the description of the BlogPost.

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
  />
</template>

Date

Use the date prop to display the date of the BlogPost.

The date is automatically formatted to the current locale. You can either pass a Date object or a string.

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    date="2024-11-25"
  />
</template>

Badge

Use the badge prop to display a Badge in the BlogPost.

Release

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    badge="Release"
  />
</template>

You can pass any property from the Badge component to customize it.

Release

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    :badge="{
      label: 'Release',
      color: 'primary',
      variant: 'solid'
    }"
  />
</template>

Image

Use the image prop to display an image in the BlogPost.

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
  />
</template>

Authors

Use the authors prop to display a list of User in the BlogPost as an array of objects with the following properties:

  • name?: string
  • description?: string
  • avatar?: Omit<AvatarProps, 'size'>
  • chip?: boolean | Omit<ChipProps, 'size' | 'inset'>
  • size?: UserVariants['size']
  • orientation?: UserVariants['orientation']

You can pass any property from the Link component such as to, target, etc.

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
 

Anthony Fu

antfu7

<script setup lang="ts">
const authors = ref([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png'
    },
    to: 'https://github.com/antfu',
    target: '_blank'
  }
])
</script>

<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    :authors="authors"
  />
</template>

When the authors prop has more than one item, the AvatarGroup component is used.

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<script setup lang="ts">
const authors = ref([
  {
    name: 'Anthony Fu',
    description: 'antfu7',
    avatar: {
      src: 'https://github.com/antfu.png'
    },
    to: 'https://github.com/antfu',
    target: '_blank'
  },
  {
    name: 'Benjamin Canac',
    description: 'benjamincanac',
    avatar: {
      src: 'https://github.com/benjamincanac.png'
    },
    to: 'https://github.com/benjamincanac',
    target: '_blank'
  }
])
</script>

<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    :authors="authors"
  />
</template>

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

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    to="https://nuxt.com/blog/nuxt-icon-v1-0"
    target="_blank"
  />
</template>

Variant

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

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    to="https://nuxt.com/blog/nuxt-icon-v1-0"
    target="_blank"
    variant="naked"
  />
</template>
The styling will be different wether you provide a to prop or an image.

Orientation

Use the orientation prop to change the BlogPost orientation. Defaults to vertical.

Introducing Nuxt Icon v1

Introducing Nuxt Icon v1

Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects.
<template>
  <UBlogPost
    title="Introducing Nuxt Icon v1"
    description="Discover Nuxt Icon v1 - a modern, versatile, and customizable icon solution for your Nuxt projects."
    image="https://nuxt.com/assets/blog/nuxt-icon/cover.png"
    date="2024-11-25"
    to="https://nuxt.com/blog/nuxt-icon-v1-0"
    target="_blank"
    orientation="horizontal"
  />
</template>

API

Props

Prop Default Type
as

'article'

any

The element or component this component should render as.

title

string

description

string

date

string | Date

The date of the blog post. Can be a string or a Date object.

badge

string | BadgeProps

Display a badge on the blog post. Can be a string or an object. { color: 'neutral', variant: 'subtle' }

authors

UserProps[]

The authors of the blog post.

image

string | Partial<HTMLImageElement>

The image of the blog post. Can be a string or an object.

orientation

'vertical'

"vertical" | "horizontal"

The orientation of the blog post.

variant

'outline'

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

to

string | RouteLocationAsRelativeGeneric | RouteLocationAsPathGeneric

target

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

ui

Partial<{ root: string; header: string; body: string; footer: string; image: string; title: string; description: string; authors: string; avatar: string; meta: string; date: string; badge: string; }>

Slots

Slot Type
date

{}

badge

{}

title

{}

description

{}

authors

{}

header

{}

body

{}

footer

{}

Theme

app.config.ts
export default defineAppConfig({
  uiPro: {
    blogPost: {
      slots: {
        root: 'relative group flex flex-col rounded-[calc(var(--ui-radius)*2)] overflow-hidden',
        header: 'relative overflow-hidden aspect-[16/9] w-full pointer-events-none',
        body: 'min-w-0 flex flex-col',
        footer: '',
        image: 'object-cover object-top w-full h-full',
        title: 'text-xl text-pretty font-semibold text-[var(--ui-text-highlighted)]',
        description: 'mt-1 text-base text-pretty',
        authors: 'mt-4 flex flex-wrap gap-x-3 gap-y-1.5',
        avatar: '',
        meta: 'flex items-center gap-2 mb-2',
        date: 'text-sm',
        badge: ''
      },
      variants: {
        orientation: {
          horizontal: {
            root: 'lg:grid lg:grid-cols-2 lg:items-center gap-x-8',
            body: 'justify-center py-4 sm:py-6'
          },
          vertical: {
            root: 'flex flex-col',
            body: 'p-4 sm:p-6'
          }
        },
        variant: {
          outline: {
            root: 'bg-[var(--ui-bg)] ring ring-[var(--ui-border)]',
            date: 'text-[var(--ui-text-toned)]',
            description: 'text-[var(--ui-text-muted)]'
          },
          soft: {
            root: 'bg-[var(--ui-bg-elevated)]/50',
            date: 'text-[var(--ui-text-muted)]',
            description: 'text-[var(--ui-text-toned)]'
          },
          subtle: {
            root: 'bg-[var(--ui-bg-elevated)]/50 ring ring-[var(--ui-border)]',
            date: 'text-[var(--ui-text-muted)]',
            description: 'text-[var(--ui-text-toned)]'
          },
          ghost: {
            date: 'text-[var(--ui-text-toned)]',
            description: 'text-[var(--ui-text-muted)]',
            header: 'shadow-lg rounded-[calc(var(--ui-radius)*2)]'
          },
          naked: {
            root: 'p-0 sm:p-0',
            date: 'text-[var(--ui-text-toned)]',
            description: 'text-[var(--ui-text-muted)]',
            header: 'shadow-lg rounded-[calc(var(--ui-radius)*2)]'
          }
        },
        to: {
          true: {
            root: [
              'transition'
            ],
            image: 'transform transition-transform duration-200 group-hover:scale-110',
            avatar: 'transform transition-transform duration-200 hover:scale-115'
          }
        },
        image: {
          true: ''
        }
      },
      compoundVariants: [
        {
          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)] hover:ring-[var(--ui-border-accented)]'
          }
        },
        {
          variant: 'ghost',
          to: true,
          class: {
            root: 'hover:bg-[var(--ui-bg-elevated)]/50',
            header: [
              'group-hover:shadow-none',
              'transition-all'
            ]
          }
        },
        {
          variant: 'ghost',
          to: true,
          orientation: 'vertical',
          class: {
            header: 'group-hover:rounded-b-none'
          }
        },
        {
          variant: 'ghost',
          to: true,
          orientation: 'horizontal',
          class: {
            header: 'group-hover:rounded-r-none'
          }
        },
        {
          orientation: 'vertical',
          image: false,
          variant: 'naked',
          class: {
            body: 'p-0 sm:p-0'
          }
        }
      ],
      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: {
        blogPost: {
          slots: {
            root: 'relative group flex flex-col rounded-[calc(var(--ui-radius)*2)] overflow-hidden',
            header: 'relative overflow-hidden aspect-[16/9] w-full pointer-events-none',
            body: 'min-w-0 flex flex-col',
            footer: '',
            image: 'object-cover object-top w-full h-full',
            title: 'text-xl text-pretty font-semibold text-[var(--ui-text-highlighted)]',
            description: 'mt-1 text-base text-pretty',
            authors: 'mt-4 flex flex-wrap gap-x-3 gap-y-1.5',
            avatar: '',
            meta: 'flex items-center gap-2 mb-2',
            date: 'text-sm',
            badge: ''
          },
          variants: {
            orientation: {
              horizontal: {
                root: 'lg:grid lg:grid-cols-2 lg:items-center gap-x-8',
                body: 'justify-center py-4 sm:py-6'
              },
              vertical: {
                root: 'flex flex-col',
                body: 'p-4 sm:p-6'
              }
            },
            variant: {
              outline: {
                root: 'bg-[var(--ui-bg)] ring ring-[var(--ui-border)]',
                date: 'text-[var(--ui-text-toned)]',
                description: 'text-[var(--ui-text-muted)]'
              },
              soft: {
                root: 'bg-[var(--ui-bg-elevated)]/50',
                date: 'text-[var(--ui-text-muted)]',
                description: 'text-[var(--ui-text-toned)]'
              },
              subtle: {
                root: 'bg-[var(--ui-bg-elevated)]/50 ring ring-[var(--ui-border)]',
                date: 'text-[var(--ui-text-muted)]',
                description: 'text-[var(--ui-text-toned)]'
              },
              ghost: {
                date: 'text-[var(--ui-text-toned)]',
                description: 'text-[var(--ui-text-muted)]',
                header: 'shadow-lg rounded-[calc(var(--ui-radius)*2)]'
              },
              naked: {
                root: 'p-0 sm:p-0',
                date: 'text-[var(--ui-text-toned)]',
                description: 'text-[var(--ui-text-muted)]',
                header: 'shadow-lg rounded-[calc(var(--ui-radius)*2)]'
              }
            },
            to: {
              true: {
                root: [
                  'transition'
                ],
                image: 'transform transition-transform duration-200 group-hover:scale-110',
                avatar: 'transform transition-transform duration-200 hover:scale-115'
              }
            },
            image: {
              true: ''
            }
          },
          compoundVariants: [
            {
              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)] hover:ring-[var(--ui-border-accented)]'
              }
            },
            {
              variant: 'ghost',
              to: true,
              class: {
                root: 'hover:bg-[var(--ui-bg-elevated)]/50',
                header: [
                  'group-hover:shadow-none',
                  'transition-all'
                ]
              }
            },
            {
              variant: 'ghost',
              to: true,
              orientation: 'vertical',
              class: {
                header: 'group-hover:rounded-b-none'
              }
            },
            {
              variant: 'ghost',
              to: true,
              orientation: 'horizontal',
              class: {
                header: 'group-hover:rounded-r-none'
              }
            },
            {
              orientation: 'vertical',
              image: false,
              variant: 'naked',
              class: {
                body: 'p-0 sm:p-0'
              }
            }
          ],
          defaultVariants: {
            variant: 'outline'
          }
        }
      }
    })
  ]
})