'Why can't I read a JSON file on Vercel when using Next.js SSR?

I have a barebones Next.js project consisting of three main files (listed below) where I'm trying to generate the index page with data from a JSON file. If I deploy the project to Vercel using getStaticProps, everything works properly.

However, when I deploy using getServerSideProps, the project builds but I get "500: Internal Server Error" when visiting the site and an error message (also listed below) in Vercel's Functions logs. I can run the app in development and deployment modes using getServerSideProps locally, just not on Vercel.

Why is the project able to find the JSON file when deployed to Vercel while using getStaticProps, but not getServerSideProps?

pages/index.tsx:

import { GetStaticProps, GetServerSideProps } from 'next';
import { User, getUsers } from '../lib/users';

// export const getStaticProps: GetStaticProps = async () => {
export const getServerSideProps: GetServerSideProps = async () => {
    const users = await getUsers();
    return { props: { users } };
};

export default function Home({ users }) {
    return (
        <div>
            {users.map((user: User) => (
                <p key={user.id}>{user.name}</p>
            ))}
        </div>
    );
}

lib/users.ts:

import fs from 'fs';

export interface User {
    id: number;
    name: string;
}

export function getUsers(): User[] {
    const users = JSON.parse(fs.readFileSync('data/users.json').toString());
    return users;
}

data/users.json:

[
    { "id": 1, "name": "Alice" },
    { "id": 2, "name": "Bob" },
    { "id": 3, "name": "Charlie" }
]

Vercel's Functions log:

[GET] /
09:41:25:73
2022-03-11T17:41:26.362Z    c8febc98-491a-4433-a2af-6dd7be25b040    ERROR   Error: ENOENT: no such file or directory, open 'data/users.json'
    at Object.openSync (fs.js:497:3)
    at Object.readFileSync (fs.js:393:35)
    at getUsers (/var/task/.next/server/pages/index.js:28:52)
    at getServerSideProps (/var/task/.next/server/pages/index.js:40:25)
    at Object.renderToHTML (/var/task/node_modules/next/dist/server/render.js:566:26)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async doRender (/var/task/node_modules/next/dist/server/base-server.js:855:38)
    at async /var/task/node_modules/next/dist/server/base-server.js:950:28
    at async /var/task/node_modules/next/dist/server/response-cache.js:63:36 {
  errno: -2,
  syscall: 'open',
  path: 'data/users.json',
  page: '/'
}
RequestId: c8febc98-491a-4433-a2af-6dd7be25b040 Error: Runtime exited with error: exit status 1
Runtime.ExitError


Solution 1:[1]

Make sure that data folder place in public folder.

public
 data
   user.json
pages
styles

and put a slash inside fs.readFileSync

export function getUsers(): User[] {
const users = JSON.parse(fs.readFileSync('/data/users.json').toString());
return users;
}

Your JSON must be like this:

{
"users" : [
  { "id": 1, "name": "Alice" },
  { "id": 2, "name": "Bob" },
 { "id": 3, "name": "Charlie" }
]
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Paiman Rasoli