How to best import “server-only” code in Next.js?

In the getServerSideProps function of my index page, I’d like to use a function foo, imported from another local file, which is dependent on a certain Node library. Said library can’t be run in the browser, as it depends on “server-only” modules such as fs or request.

I’ve been using the following pattern, but would like to optimize it. Defining foo as mutable in order to have it be in scope is clunky and seems avoidable.

let foo;
if (typeof window === "undefined") {
  foo =  require("../clients/foo");
}

export default function Index({data}) {
  ...
}

export async function getServerSideProps() {
  return {
    props: {data: await foo()},
  }
}

What would be the best practice here? Is it somehow possible to leverage ES6’s dynamic import function? What about dynamically importing within getServerSideProps?

I’m using Next.js version 9.3.6.

Thanks.

UPDATE:

It seems as if Next.js’s own dynamic import solution is the answer to this. I’m still testing it and will update this post accordingly, when done. The docs seem quite confusing to me as they mentionn disabling imports for SSR, but not vice versa.

https://nextjs.org/docs/advanced-features/dynamic-import

Answer

When using getServerSideProps/getStaticProps Next.js will automatically delete all server-only code from the client-side bundle. There’s no risk of running server code on the browser.

You can use the Next.js Code Elimination tool to verify what gets bundled for the client-side. You’ll notice that getServerSideProps/getStaticProps gets removed as do the imports used by it.

Leave a Reply

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