The BlogPosts component provides a flexible layout to display a list of BlogPost components using either the default slot or the posts prop.
<template>
<UBlogPosts>
<UBlogPost
v-for="(post, index) in posts"
:key="index"
v-bind="post"
/>
</UBlogPosts>
</template>
Use the posts prop as an array of objects with the properties of the BlogPost component.


<script setup lang="ts">
const posts = ref([
{
title: 'Nuxt Icon v1',
description: 'Discover Nuxt Icon v1!',
image: 'https://nuxt.com/assets/blog/nuxt-icon/cover.png',
date: '2024-11-25'
},
{
title: 'Nuxt 3.14',
description: 'Nuxt 3.14 is out!',
image: 'https://nuxt.com/assets/blog/v3.14.png',
date: '2024-11-04'
},
{
title: 'Nuxt 3.13',
description: 'Nuxt 3.13 is out!',
image: 'https://nuxt.com/assets/blog/v3.13.png',
date: '2024-08-22'
}
])
</script>
<template>
<UBlogPosts :posts="posts" />
</template>
Use the orientation prop to change the orientation of the BlogPosts. Defaults to horizontal.


<script setup lang="ts">
const posts = ref([
{
title: 'Nuxt Icon v1',
description: 'Discover Nuxt Icon v1!',
image: 'https://nuxt.com/assets/blog/nuxt-icon/cover.png',
date: '2024-11-25'
},
{
title: 'Nuxt 3.14',
description: 'Nuxt 3.14 is out!',
image: 'https://nuxt.com/assets/blog/v3.14.png',
date: '2024-11-04'
},
{
title: 'Nuxt 3.13',
description: 'Nuxt 3.13 is out!',
image: 'https://nuxt.com/assets/blog/v3.13.png',
date: '2024-08-22'
}
])
</script>
<template>
<UBlogPosts orientation="vertical" :posts="posts" />
</template>
When using the posts prop instead of the default slot, the orientation of the posts is automatically reversed, horizontal to vertical and vice versa.
While these examples use Nuxt Content, the components can be integrated with any content management system.
Use the BlogPosts component in a page to create a blog page:
<script setup lang="ts">
const { data: posts } = await useAsyncData('posts', () => queryCollection('posts').all())
</script>
<template>
<UPage>
<UPageHero title="Blog" />
<UPageBody>
<UContainer>
<UBlogPosts>
<UBlogPost
v-for="(post, index) in posts"
:key="index"
v-bind="post"
:to="post.path"
/>
</UBlogPosts>
</UContainer>
</UPageBody>
</UPage>
</template>
In this example, the posts are fetched using queryCollection from the @nuxt/content module.
The to prop is overridden here since @nuxt/content uses the path property.
| Prop | Default | Type |
|---|---|---|
as |
|
The element or component this component should render as. |
posts |
| |
orientation |
|
The orientation of the blog posts. |
| Slot | Type |
|---|---|
date | |
badge | |
title | |
description | |
authors | |
header |
|
body | |
footer |
|
default |
|
export default defineAppConfig({
ui: {
blogPosts: {
base: 'flex flex-col gap-8 lg:gap-y-16',
variants: {
orientation: {
horizontal: 'sm:grid sm:grid-cols-2 lg:grid-cols-3',
vertical: ''
}
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
blogPosts: {
base: 'flex flex-col gap-8 lg:gap-y-16',
variants: {
orientation: {
horizontal: 'sm:grid sm:grid-cols-2 lg:grid-cols-3',
vertical: ''
}
}
}
}
})
]
})