Serverside component for Next.js

Viewed 372

I am working on an open-source package meant to be used by a Next.js app. One of the components is a replacement for Link. In my package, the APIs are exposed using exports in package.json, like this:

"exports": {
    "./link": "./lib/link/index.js",
    "./link-ssr": "./lib/link/ssr.js"
  }

Because it requires server-side rendering, I have two versions of the Link component, one for the client and the other one for SSR. The way I was able to get SSR to work was to use this special Webpack config (on the app that uses my package) in next.config.js:

  webpack(config, { isServer }) {
    if (isServer) {
      config.resolve.alias['my-package/link'] = require.resolve(
        'my-package/link-ssr'
      );
    });

Because link-ssr is only used internally, I was trying to find a way to avoid exposing its API. One way I thought of using was to use a conditional isServer variable inside the client link component:

const isServer = typeof window === 'undefined'

if (isServer) {
  // Do server stuff
} else {
  // Do client stuff
}

The server component relies on fs (file server) and when I do this I get a Next.js compilation error when trying to access a page that uses the component:

event - compiled successfully
event - build page: /
wait  - compiling...
error - ../lib/Links.js:5:0
Module not found: Can't resolve 'fs'
  3 | exports.Links = void 0;
  4 | const path_1 = require("path");
> 5 | const fs_1 = require("fs");
  6 | /** Local rewrite cache to avoid non-required file system operations. */
  7 | let linksCache;
  8 | /**

Is this even feasible or are there other ways to avoid exposing link-ssr as a public component?

1 Answers

You can give it a try with environment Variables. No need for additional dependencies.

For that, create an .env.production in your root-directory and put a Variable in there:

IS_SERVER=true

Then in your Sorcecode you can work with this ENV-Variable to check if you are at the Server or not:

export async function getStaticProps() {
  isServer = process.env.IS_SERVER;
}

Related