1

I'm making static Next.JS app with MongoDB.

In my static Next.JS app can I use api routes for building pages? For example, using GET method for getting products in getStaticProps? Or it's bad approach.

Now I'm using classic way from documentation (direct calls to db, like find etc).

juliomalves
  • 42,130
  • 20
  • 150
  • 146
andrewnosov
  • 374
  • 4
  • 14
  • Does this answer your question: [Fetch error when building Next.js static website in production](https://stackoverflow.com/a/66206394/1870780)? – juliomalves Jan 26 '22 at 07:26

2 Answers2

1

You probably can but it's a bad practice to use API routes in getStaticProps/getStaticPaths as stated in the docs.

You should not fetch an API route from getStaticProps — instead, you can write the server-side code directly in getStaticProps.

Note: You should not use fetch() to call an API route in getServerSideProps. Instead, directly import the logic used inside your API route. You may need to slightly refactor your code for this approach. Fetching from an external API is fine!

Roman Mkrtchian
  • 2,548
  • 1
  • 17
  • 24
  • Thanks for this very useful information! "Fetching from an external API is fine!" — is it methods ```find, findById, etc``` which directly sends to db? – andrewnosov Feb 28 '21 at 17:20
1

As Roman, points out in his response, it is not ideal to do that.

However, you can leverage a getStaticProps to fetch the documents you need from your database. If you were rendering dynamically the classic use case of use profiles, it'd prolly look like the following pseudo-code, and assuming that you've got some sort of Model to interface your MongoDb:

// under app/pages/users/[userId].js

import UserProfile from 'components/user-profile';
import User from 'models/user';

export default UserProfile;

// both at request time and build time, preps the props passed to the UserProfile component.
export const getStaticProps = async ({params}) => {
  const user = await User.find(params.id);
  return { 
    props: { user }
  }
}

Bonus track: if your use case supports it, turning this into a statically generated site it's pretty straight-forward:

// instructs next to render all user profiles using SSG
export const getStaticPaths = async () => {
  const users = await User.findAll();
  const paths = users.map(user => `/users/${user.id}`);
  return { paths, fallback: false }; 
}
Vicente Reig
  • 877
  • 9
  • 14