Open In App

How to Make Next.js getStaticProps Work With Typescript?

Last Updated : 08 Aug, 2024
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Next.js is a popular React framework that developers use to create efficient server-rendered and static applications. One of the key features is to fetch data at build time, using a function called getStaticProps.

This function enables developers to make static pages that are served fast to users, thereby making the performance and SEO better. In this article, we will learn how to effectively use getStaticProps with TypeScript to keep type safety and improve the experience when developing.

Prerequisites

Steps To Implement getStaticProps with TypeScript

Step 1: Initialize a Next.js Project with TypeScript

npx create-next-app@latest --typescript
iimmaggee
Next.js Project

Step 2: Install Additional Dependencies (if needed)

npm install --save-dev typescript @types/react @types/node

Dependencies

"dependencies": {
    "next": "14.2.5",
    "react": "^18",
    "react-dom": "^18"
}

Folder Structure

folder-structureeee
Folder Structure

Approach 1: Using TypeScript Interfaces or Types.

Using TypeScript interfaces or types helps ensure that the data fetched in getStaticProps stick to a specific structure, making your code safer and easier to manage.

interface MyProps {
    data: string[];
}

export const getStaticProps: GetStaticProps<MyProps> = async () => {
    const data = ["item1", "item2", "item3"];
    return {
        props: {
            data,
        },
    };
};

Example: Using TypeScript interfaces or types.

JavaScript
//src/app/page.tsx

import { FC } from 'react';
const fetchMessage = async (): Promise<string> => {
    // Simulate fetching data from an API
    return 'Hello, Next.js with TypeScript!';
};

const Page: FC = async () => {
    const message = await fetchMessage();
    return <h1>{message}</h1>;
};

export default Page;

Output

example-1
Using TypeScript interfaces or types.

Approach 2: Utilizing Next.js's Built-in Types.

Next.js provides built-in types for getStaticProps which can be used to ensure type safety without manually defining the types. This approach is more concise and uses Next.js's capabilities to infer types.

import { GetStaticProps } from 'next';

type MyProps = {
    data: string[];
};

export const getStaticProps: GetStaticProps<MyProps> = async () => {
    const data = ["item1", "item2", "item3"];
    return {
        props: {
            data,
        },
    };
};

Example: Using Next.js in-built types

JavaScript
//src/app/page.tsx

import React from 'react';

async function fetchPosts(): Promise<Post[]> {
    const res = await fetch('https://jsonplaceholder.typicode.com/posts');
    if (!res.ok) {
        throw new Error('Failed to fetch posts');
    }
    return res.json();
}

export default async function Page() {
    const posts = await fetchPosts();
    return (
        <div>
            <h1>Posts</h1>
            <ul>
                {posts.map((post) => (
                    <li key={post.id}>
                        <h2>Post Title : {post.title}</h2>
                        <p>Post Summary : {post.body}</p>
                    </li>
                ))}
            </ul>
        </div>
    );
}

Output

example-2
Using Next.js in-built types

Approach 3: Combining Static Typing with Dynamic Data Fetching

In some cases where you need to handle dynamic data fetching alongside static typing, you can combine these approaches effectively. This is useful when the data structure may vary or when working with APIs that have dynamic responses.

import { GetStaticProps } from 'next';

type MyProps = {
    users: { id: number; name: string }[];
};

export const getStaticProps: GetStaticProps<MyProps> = async () => {
    const response = await fetch('https://jsonplaceholder.typicode.com/users');
    const users = await response.json();

    return {
        props: {
            users,
        },
    };
};

Example : Combining Static Typing with Dynamic Data Fetching

JavaScript
//src/app/page.tsx

import React from 'react';

type Post = {
    id: number;
    title: string;
    body: string;
};

const PostsPage = async () => {
    let posts: Post[] = [];
    let error: string | null = null;

    try {
        const res = await fetch('https://jsonplaceholder.typicode.com/posts');
        if (!res.ok) {
            throw new Error(`Failed to fetch posts: ${res.status} - ${res.statusText}`);
        }
        posts = await res.json();
    } catch (err: any) {
        error = err.message;
    }

    if (error) {
        return <div>Error: {error}</div>;
    }

    return (
        <div>
            {posts.map((post) => (
                <div key={post.id}>
                    <h1>{post.title}</h1>
                    <p style={{ color: 'blue' }}>{post.body}</p>
                </div>
            ))}
        </div>
    );
};

export default PostsPage;

Output

example-3
Combining Static Typing with Dynamic Data Fetching

Note: Run the project and open the localhost port

npm run dev

Article Tags :

Similar Reads