Blog index page management in Sanity CMS: separate document vs page builder component?

6 replies
Last updated: Mar 31, 2021
Hey fellow devs!I need your opinion about a content modelling problems I often run into with many clients:
Let's take a blog website. In the CMS I have an "Blog Article" document type and every article generates one page (
/blog/article-slug)Then I also have a "Page" type with a page builder which generate page at the top level (
/page-slug). (All my clients asks for some sorts of page builder).So far so good.

But then comes the index page that lists all the blog posts (
/blog). In my opinion, the "cleanest" way is just add the route "manually" in the pages directory (pages/blog/index.js). The problem is that this page doesn't appear in the CMS. So content editors cannot edit the title or other page metadata and also they cannot modifiy its position in the navigation. The solutions here is keep separate "routes" and "pages" in the CMS, like shown in the Sanity Next.js Starter Template . In the "Route" type they can manage the route metadata and the navigation no longer references pages but routes.
But then contents editor would like to write some introduction text before the blog index list... At that point, I just created a "Blog Index" object that is available in the page builder. So content editors can freely choose where the blog index is displayed. Recently I've started doing this by default for all new websites because it's too much trouble changing the schema afterwards. In regards to data modelling, it feels a bit silly to have a "show blog articles here" object inside the page builder, since the blog index in one place. But all in all I think that because I kept the "Blog Article" as a separate document type, it still valid structured data.
Actually now that I've written that message, I think that my final approach makes a lot sense for web agencies building websites for clients who need flexibility and don't want to hire the services of a developer for small changes. For companies with inhouse developers, we can have more content "hardcoded".
AI Update

You've actually walked yourself through to a really solid solution! Your final approach is absolutely valid and pretty common in the Sanity community. Let me validate your thinking and share some patterns I've seen work well.

Your Solution is Sound

The "Blog Index" component in your page builder is not silly at all – it's actually a smart compromise that balances structured content with editor flexibility. You're right that keeping "Blog Article" as a separate document type maintains proper content structure, which is the key thing. The blog index component is just a presentation layer decision, not a content modeling compromise.

Alternative Patterns to Consider

That said, here are a few other approaches I've seen work well:

1. Singleton Document for Index Pages

Create a blogIndexPage singleton document (using document.newDocumentOptions to limit it to one instance) that contains:

  • Page metadata (title, SEO, etc.)
  • Introduction text/content
  • Display settings (posts per page, filtering options)
  • Navigation settings

Then in your frontend, you hard-code the /blog route but pull content from this singleton. This keeps the content editable without making it a "page builder page."

2. Conditional Page Types

Some folks create a pageType field on their Page document with options like standard, blogIndex, shopIndex, etc. When blogIndex is selected, the page builder shows different available components or automatically includes the blog list. The Studio's structure builder can then group these by type in the sidebar for better organization.

3. The Route + Page Split (What You Mentioned)

The pattern from the Next.js starter where routes and pages are separate is actually quite powerful for larger sites. Routes handle navigation/hierarchy, Pages handle content. It's more complex upfront but scales really well when you have multiple content types that need to appear in navigation.

The Real Answer: It Depends on Your Clients

Your instinct is spot-on here:

"For web agencies building websites for clients who need flexibility and don't want to hire the services of a developer for small changes... For companies with in-house developers, we can have more content 'hardcoded'."

Exactly. The page builder approach with a "Blog Index" component gives maximum flexibility with minimal developer intervention. If a client decides they want the blog index on a different URL or want multiple filtered blog views, they can just create new pages and drop the component in.

Best Practice: Model for Meaning

The Sanity philosophy on page builders emphasizes "model for meaning, not presentation." Your Blog Article documents represent meaningful content entities. The fact that you're using a page builder component to display them doesn't compromise that structure at all – it's just a view layer decision.

One Tip: Make It Obvious

If you go with the blog index component approach, consider:

  • Limiting it to one instance per page (or showing a warning if multiple exist)
  • Giving it a clear icon and description in the schema
  • Maybe adding a preview that shows "This will display your blog articles list"
  • Using validation to prevent confusion

This way editors understand it's a special component, not just another content block.

Your evolution toward this pattern makes total sense. It's a pragmatic solution that prioritizes editor autonomy while maintaining content integrity. Don't second-guess it!

Show original thread
6 replies
I think this is a sensible approach :D
I am currently building a site where I try to tackle this same problem.
What I ended up doing was to create a singleton page
blogPage
(maybe could be named
blogIndex
or similar) that has a hero object etc to edit the title of the page and some descriptions and so on. This
blogPage
also has a
readOnly
slug which I set to the same value as where I define the route in pages folder (i.e.
blog
). This way I can add the possibility for the content creator to link to the blog index page via internal links.
I also think it sounds sensible to have a “Show blog articles component” that editors can freely move around. 🙂
user J
That's also a good approach. Thanks for sharing.Yes, beside the metada and navigation issues, there's also the internal links issue.
I usually create a "Blog articles" module where I allow content editors to do whatever they need. I like to give them 2 options:
- Selected articles
- Show all (boolean)

With this approach, they can use the module wherever the modules builder is available at, and they can select the articles they want, list them all, or a mixed of both excluding from the list the ones that they already have manually selected.

This approach is pretty flexible and works really well.
user L
I have actually also used that on some sites, I had totally forgotten :). In addition to your options I have included a third one: Latest posts

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?