6
124
Invalid date

Typescript version of getStaticProps, getStaticPath, and getServerSideProps in NextJS

Invalid date3 Minutes

Typescript version of getStaticProps, getStaticPath, and getServerSideProps in NextJS

Introduction

As someone new to TypeScript, getting the type right can be frustrating, so I will show you how to display data from Sanity CMS without any type error.

Firstly, if this is the first time hearing about Sanity CMS, it is an open-source headless real-time content management system, that can be used by any Web Framework. And it let you structure your content however you see fit, to build better digital experiences.

For more information on Sanity CMS. Check the reference tab on your right.😉

Let's Start

So, there are two ways to get data from Sanity:

  • Using Sanity API URL
  • Queries (Which we will use here)
  • CURL (I use it for testing, don't know for others)

In this article, we focus on the Queries. There are two places we will display data, and that's the index.tsx and post/[post].tsx.

In JavaScript, this is how it looks.

import { Layout } from '../components';
import { Client } from '../services/';

const Home = ({post_card}) => {
  console.log('result',post_card)
  //data show in the browser console
  return (
    <Layout>
    //code
    </Layout>
  );
};

export default Home;

export const getServerSideProps = async () => {
  const post = `*[_type == "post"]{
  author->{
  name,
 "image": image.asset->url,
  slug,
},
  slug,
  "image": mainImage.asset->url,
  short_description,
  title,
  featured_post,
  recommended_post,
  publishedAt,
  category->{
    name,
    slug,
  },
}`;

  const post_card = await Client.fetch(post);

  if (!post_card) {
    return {
      error: true,
      data: [],
    };
  } else {
    return {
      props: {
        post_card,
      },
    };
  }
};

Simple, right? No need to add types to it and the data gets displayed inside the console or terminal.

But with TypeScript, this would show red marks all over your code, because TypeScript is a strongly typed language, and allows the developer to specify the types of data being passed around within the code and has the ability to report errors when the types don't match.

So these three, getStaticProps, getStaticPath, and getServerSideProps have types in NextJS.

 // For getStaticProps
import { GetStaticProps } from 'next'

// For getStaticPaths
import { GetStaticPaths } from 'next'

// Fro getServerSideProps
import { GetServerSideProps } from 'next'

Therefore, in JavaScript, this is how it looks.

import { Layout } from '../../components';
import { Client } from '../../services';
import { GetStaticProps, GetStaticPaths, InferGetServerSidePropsType} from 'next';
import { ParsedUrlQuery } from 'querystring';
import { groq } from 'next-sanity';


interface Params extends ParsedUrlQuery {
  thought: string;
}

interface BodyProps {
  markDefs?: {
    _key: string;
    _type: string;
    href: string;
  }[];
  level?: number;
  listItem?: string;
  style: string;
  _key: string;
  _type: string;
  children: {
    _key: string;
    _type: string;
    marks?: {
      text: string;
      _key: string;
      _type: string;
    }[];
    text: string;
  };
}

interface ThoughtsProps {
  _id: string;
  author: {
    name: string;
  };
  title: string;
  categories: {
    title: string;
  }[];
  reference_post: {
    name: string;
    url: string;
  }[];
  body: BodyProps;
  viewCount: number;
  publishedAt: string;
  _createdAt: string;
  _updatedAt: string;
  featured: boolean;
  recommended: boolean;
  image: string;
  slug: { current: string };
  comment: Comment[];
  all_post: {
    title: string;
    image: string;
    featured: string;
    recommended: string;
    description: string;
    slug: {
      current: string;
    };
  };
}

interface Props {
  title: string;
  image: string;
  featured: string;
  recommended: string;
  description: string;
  slug: {
    current: string;
  };
}
[];

const Thoughts = ({ thoughtData, allData}: InferGetServerSidePropsType<typeof getStaticProps>) => {

console.log('result', {thoughtData, allData})
// data shows in the console or terminal.
  return (
    <Layout>
   // some code
    </Layout>
  );
};

export default Thoughts;

export const getStaticPaths: GetStaticPaths = async () => {
  interface QueryProps {
    slug: {
      current: string;
    };
  }

  const query = `*[_type == "post"]{
  slug{
  current
}
}`;

  const post_paths: QueryProps[] = await Client.fetch(query);

  const paths = post_paths.map((path) => ({
    params: {
      thought: path.slug.current,
    },
  }));

  return {
    paths,
    fallback: false,
  };
};

export const getStaticProps: GetStaticProps<{
  thoughtData: ThoughtsProps;
  allData: Props;
}> = async (context) => {
  const { thought } = context.params as Params;

  const query = groq`*[_type == "post" && slug.current == "${thought}" ][0]{
        _id,
        title,
        body,
          author->{
            name,
            "image":image.asset->url,
          },
        viewCount,
          reference_post[]{
            name,
            url,
          },
          publishedAt,
          _createdAt,
          _updatedAt,
          categories[]->{
            title,
          },
          featured,
          recommended,
          slug{current},
        "image": mainImage.asset->url,
        "comment": *[_type == "comment" && post._ref == ^._id][]{
            name,
            email,
            profile,
            comment,
            _createdAt,
            _updatedAt
        }
    }`;

  const query2 = groq`*[_type == "post"][]{
    _id,
  "image": mainImage.asset->url,
   title,
   viewCount,
  featured,  
  description,
  recommended,
  slug{
  current,
  },
  "comment": *[_type == "comment" && post._ref == ^._id][],
}
`;

  const thoughtData: ThoughtsProps = await Client.fetch(query);
  const allData: Props = await Client.fetch(query2);

  if (!thoughtData) return { notFound: true };

  return {
    props: {
      thoughtData,
      allData,
    },
  };
};

And that's how you can display data from Sanity CMS with TypeScript without any types errors.

Conclusion

This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you.

Rocky EsselMongoDB BlogMongoDB BlogMongoDB BlogMongoDB BlogMongoDB Blog6+
6 comment
Rocky Essel
February 1, 2023 3:11 PM

This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you. This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you. This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you.This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you.This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you.This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you.This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you.This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you.This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you. This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you. This is my first time sharing information on the internet through something I've built, so if there's was something you felt I couldn't communicate better, please let me know in the comment section. Thank you.

MongoDB Blog
February 1, 2023 7:21 PM

hey man, just wanted to say nice portfolio website

MongoDB Blog
February 1, 2023 7:25 PM

hey man, just wanted to say nice portfolio website

MongoDB Blog
February 1, 2023 7:19 PM

hey man, just wanted to say nice portfolio website

MongoDB Blog
February 1, 2023 7:23 PM

hey man, just wanted to say nice portfolio website

MongoDB Blog
February 1, 2023 7:25 PM

hey man, just wanted to say nice portfolio website