If you’re a developer working with Next.js, you may have found yourself needing to load data from a file in your application. This could be anything from a JSON file containing configuration settings to a CSV file with data that needs to be processed and displayed on your site.

Loading data from a file in Next.js is a common task, but it can be confusing if you’re not familiar with the process. Fortunately, it’s a straightforward process that can be done in just a few simple steps.

In this article, we’ll walk you through how to load data from a file in Next.js, starting with the basics and working our way up to more advanced techniques. By the end, you’ll be equipped with the knowledge you need to confidently work with data files in your Next.js applications. So let’s dive in!

Imports

To load data from a file in Next.js, you have several options depending on the type of file you’re working with. In this section, we’ll explore some of the most common ways to load data from different file formats.

If you’re using JSON, the easiest way to load your JSON file is using an import:

import data from './data.json';

One of the benefits of this is that if you’re using TypeScript, you will get type-checking on your JSON file. The file gets imported into a variable, which you’re then able to use wherever you need. For a quick example, here’s a sample JSON file:

{
  "users": [
    "Adam",
    "Brian",
    "Carl",
    "Ruby",
    "Edward"
  ],
  "admins": [
    "Adam",
    "Ruby"
  ]
}
export default function Data() {
    const {
        users, admins,
    } = data;
    return <div className='w-full h-screen flex items-center justify-center'>
        <ul className='flex flex-col gap-4'>{users.map((u) => <ListItem key={u} user={u} admin={admins.includes(u)} />)}
        </ul>
    </div>;
}

Just a simple component to display our data, with some styling from Tailwind. Here’s what it looks like:

Dynamic File Loading

The above method only works if you’re able to import your file, and only if you know the file you need to load at the start. Let’s get rid of both of those, and load a regular text file, that we don’t know in advance.

We’re going to be using the fs API, which is a set of functions for reading and writing files in JavaScript. The first thing to note is that this API doesn’t exist in the browser, which means that we need to do our file loading in one of Next.js’ pre-rendering methods. I’ll be using getStaticProps.

Here are the files we’ll be loading:

And for an example of what’s in one of them:

age=22
admin=true

I want to be able to load the files from this folder into an array, storing each user as a tuple.

Here’s my getStaticProps method:

export async function getStaticProps() {
    const userFiles = fs.readdirSync('./src/pages/upmostly/files');
    const users = userFiles.map((filename) => {
        const name = filename.split('.')[0];
        const data = fs.readFileSync(path.join('./src/pages/upmostly/files', filename), 'utf8');
        const variables = Object.fromEntries(data.split('\r\n').map((v) => v.split('=')));
        const age = Number(variables['age']);
        const admin = variables['admin'] == 'true';

        return [name, age, admin];
    });

    return {
        props: { users }, // will be passed to the page component as props
    };
}

That’s quite a lot of code, so let’s break this down:

    const userFiles = fs.readdirSync('./src/pages/upmostly/files');

This gives us back a list of files in our folder, very simple.

    const users = userFiles.map((filename) => {
        const name = filename.split('.')[0];
        const data = fs.readFileSync(path.join('./src/pages/upmostly/files', filename), 'utf8');
        const variables = Object.fromEntries(data.split('\r\n').map((v) => v.split('=')));
        const age = Number(variables['age']);
        const admin = variables['admin'] == 'true';

        return [name, age, admin];
    });

I’m then mapping over this array, and

  • Getting the user name from the filename
  • Loading the contents of the file
  • Splitting the file into separate lines
  • Splitting each variable into its key and value
  • Converting the age to a number
  • Converting the admin flag to a boolean

We can then combine these into a tuple array, and return them.

Then we pass this to our page by returning them inside props:

    return {
        props: { users }, // will be passed to the page component as props
    };

Then onto our front-end:

export default function Data({ users }: { users: [string, number, boolean][] }) {

    return <div className='w-full h-screen flex items-center justify-center flex flex-col'>
        {users.map(([name, age, admin]) => <div key={name}><h2
            className={clsx('capitalize', admin && 'text-green-600')}>{name}</h2>
            <p>Age: {age}</p>
        </div>)}
    </div>;
}

We get passed our data through props to use in our component. Then I’m displaying the data simply, with some styling from TailwindCSS. Here’s what our page looks like:

Conclusion

Thanks for reading! We’ve covered two approaches to loading files in Next.js. Imports are the simplest approach, great for if the type of file is one that is supported for importing, e.g. JSON, and the file is available at build time. For more complex situations, using the fs API and Server-Side Rendering, or Static Site Generations to pass in the contents of the file as props is a good approach. If you liked this article, leave a comment below!

Avatar photo
👋 Hey, I'm Omari Thompson-Edwards
Hey, I'm Omari! I'm a full-stack developer from the UK. I'm currently looking for graduate and freelance software engineering roles, so if you liked this article, reach out on Twitter at @marile0n

💬 Leave a comment

Your email address will not be published. Required fields are marked *

We will never share your email with anyone else.