Post retrieval on my index page

9 replies
Last updated: Jan 1, 2021
Hi, I'm trying to make a simple blog using Sanity and I'm stuck on post retrieval on my index page. I'm currently writing this code in typescript + nextjs and here's a snippet on what I'm having problems with. I don't know how to specify a type for Posts. Is there an inbuilt type or do I have to make my own?
export default function Index(props) {
  return (
    <div>
      <h1>Welcome to a blog!</h1>
      {props.posts.map(
        ({ _id, title = '', slug = '', _updatedAt = '' }) =>
          slug && (
            <li key={_id}>
              <Link href="/blog/post/[slug]" as={`/blog/post/${slug.current}`}>
                <a>{title}</a>
              </Link>{' '}
              ({new Date(_updatedAt).toDateString()})
            </li>
          )
      )}
    </div>
  );
}

export async function getStaticProps() {
  const posts = await sanity.fetch(`*[_type == "post"]|order(publishedAt desc)`);

  console.log(posts);

  console.log(typeof posts);

  return {
    props: {
      posts: posts
    }
  };
}
AI Update

You'll want to use Sanity TypeGen to automatically generate TypeScript types for your posts! This is the recommended approach that eliminates manual type definitions.

Quick Setup

First, generate types from your schema and queries:

npx sanity typegen generate

This creates a sanity.types.ts file with types for all your schema documents.

Update Your Code

Here's how to properly type your component using the generated types:

import { defineQuery } from 'next-sanity'
import type { POST_QUERYResult } from '@/sanity.types' // adjust path as needed

const POST_QUERY = defineQuery(`*[_type == "post"] | order(publishedAt desc)`)

export async function getStaticProps() {
  const posts = await sanity.fetch(POST_QUERY);
  // posts is now automatically typed!
  
  return {
    props: {
      posts
    }
  };
}

interface IndexProps {
  posts: POST_QUERYResult
}

export default function Index({ posts }: IndexProps) {
  return (
    <div>
      <h1>Welcome to a blog!</h1>
      {posts.map(({ _id, title = '', slug, _updatedAt = '' }) =>
        slug && (
          <li key={_id}>
            <Link href={`/blog/post/${slug.current}`}>
              {title}
            </Link>{' '}
            ({new Date(_updatedAt).toDateString()})
          </li>
        )
      )}
    </div>
  );
}

How It Works

The defineQuery helper does two things:

  1. Enables syntax highlighting for your GROQ queries (with the Sanity VS Code extension)
  2. Tells TypeGen to generate types for that specific query result

When you run npx sanity typegen generate, it scans your code for defineQuery calls and creates corresponding TypeScript types named after your variable (e.g., POST_QUERY becomes POST_QUERYResult).

Pro Tips

  • Re-run npx sanity typegen generate whenever you change your schema or queries
  • You can add a script to your package.json: "typegen": "sanity typegen generate"
  • The types are automatically inferred when using client.fetch(), so TypeScript knows exactly what shape your data is

This approach is much better than manually creating types because your types stay in sync with your actual schema and queries automatically! If you want more control over runtime validation, there's also groqd, but for most cases the built-in TypeGen is the way to go.

you have to make your own, or use a tool that generate types. you could try out https://github.com/ricokahler/sanity-codegen if you don't want to type your own
I really appreciate that. Thank you!
Follow up question: Where can I find documentation about schemas since this generator requires a schema path?
do you mean general sanity schemas docs?
I believe that's what it requires, so yes
https://www.sanity.io/docs/schema-types
https://www.sanity.io/guides/how-to-configure-schemas
there are two sources about schema &amp; their types, I guess you can find much more on
sanity.io site
Ok, the second one is what I needed, thank you!
No worries!
Wasn't sure how to configure/structure schemas

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?