How to deal with archive pages of blog posts in Sanity

11 replies
Last updated: Mar 30, 2023
How would I deal with archive pages of blog posts? I have a normal Post model.
I have a pageBuilder array of sections for all pages and shared settings, navigation etc.

But a blog overview page with a pageBuilder is not the solution.

Would I create a singleTon for the blog archive and if so, what goes in there to show all the existing posts?
AI Update

Yes, creating a singleton for the blog archive page is a great approach! Here's how you'd set this up:

The Singleton Approach

A singleton document is perfect for your blog archive page because it's a unique page that only needs one instance. Unlike your regular pages with pageBuilder arrays, the blog archive singleton would contain metadata and settings specific to the archive page, while your actual posts are queried dynamically.

What Goes in the Singleton

Your blog archive singleton might look like this:

export const blogArchive = defineType({
  name: 'blogArchive',
  title: 'Blog Archive',
  type: 'document',
  fields: [
    defineField({
      name: 'title',
      type: 'string',
      title: 'Page Title'
    }),
    defineField({
      name: 'description',
      type: 'text',
      title: 'Page Description'
    }),
    defineField({
      name: 'seo',
      type: 'seo', // your SEO object
    }),
    defineField({
      name: 'postsPerPage',
      type: 'number',
      title: 'Posts Per Page',
      initialValue: 10
    }),
    // Optional: featured posts
    defineField({
      name: 'featuredPosts',
      type: 'array',
      of: [{ type: 'reference', to: [{ type: 'post' }] }]
    })
  ]
})

Fetching Posts in Your Frontend

The singleton stores settings, not the posts themselves. You'd query posts separately using GROQ:

// Get the archive settings
const archiveSettings = await client.fetch(`*[_type == "blogArchive"][0]`)

// Get all posts (sorted by date)
const posts = await client.fetch(`
  *[_type == "post"] | order(publishedAt desc) {
    _id,
    title,
    slug,
    excerpt,
    publishedAt,
    author->
  }
`)

Setting Up the Singleton

You'll need to configure your sanity.config.js to make it a proper singleton by customizing the Structure Builder, filtering templates, and limiting document actions. The singleton document guide has the full implementation details, or you can use the singleton-tools plugin for easier setup.

This approach keeps your content architecture clean: regular pages use pageBuilder for flexibility, while the blog archive uses a singleton for configuration + dynamic GROQ queries for the actual post list.

This would be handled just in your frontend no?
You could have a model to maybe set the page title and any extra copy needed for the blog archive page, but no need to list out all the blog entries in model in Sanity also
So /pages/blog/index.tsx would have a unique query only to display all the archives. But what if I want to have a Hero section from the pageBuilder array but I want to display all the blog posts no matter what. How would I deal with that? That is basically my only issue now
yeah than add the Hero into the model so you can set that in Sanity.
You just need to add a query in nextjs that retrieves the blog posts also alongside the page content
So you would have a blogArchive model which has all the fields set that you want added to Sanity.
Then in Nextjs, you make your query to blogArchive type and also query blogPost type with the fields you need
https://blog.novacare.no/multiple-queries-in-sanity-with-one-request/ is a nice example of combining multiple queries into 1
Aahhhhh, I get it.Since I dont need the pageBuilder on the archive I only need to copy the Hero section with a title, image, text and query this data on the /blog/index.tsx together with a another query to display alll the posts right?
Unique model for the archive only which matches the design right?
Yup
Thank you User! Appreciate it
np!
Great article btw thanks this will help

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?