Netlify Nextjs Plugin Causes Build Errors (Works Without It)

General Information

Overview
So I’ve been trying to get a Next.js application with SSR (we use getServerSideProps) working on Netlify. I’ve used Netlify heavily in the past but also with SSG applications/websites.

I’m getting a strange issue that only appears when using the Next.js plugin (I tested it by setting/removing target:serverless.

Essentially it appears when using the plugin it registers all of the pages, even though it works fine otherwise.

I’ve gone through every example and posting I could find online as to how to resolve this issue. Most of the other “found pages without a React Components” are people defining non-page files in the /pages directory.

Example Structure Of Files In Pages Directory

import { SignIn } from "../../Registration/SignIn/SignIn";
import {
  withoutAuthorization,
  withoutServerSideAuthorization,
} from "../../HOCs/authorization.hocs";

export default withoutAuthorization(SignIn);

export const getServerSideProps = withoutServerSideAuthorization(() => {
  return { props: {} };
});

Higher Order Components

function withoutAuthorization<T>(

  WrappedComponent: React.ComponentType<T>

): React.ComponentType<T> {

  const UnauthorizedComponent: React.FC<T> = (props) => {

    const router = useRouter();

    const { accessToken, userId } = useStoreState(

      (state) => state.authentication

    );

    const companyId = useStoreState(

      (state) => state.user.userById[userId]

    )?.companyId;

    const isInBrowser = typeof window !== "undefined";

    if (isInBrowser && accessToken) {

      if (!companyId) {

        router.push("/auth/onboarding");

      } else {

        router.push("/");

      }

    }

    return <WrappedComponent {...props} />;

  };

  return UnauthorizedComponent;

}

type GetServerSidePropsHandler<P> = () => GetServerSidePropsResult<P>;

const withoutServerSideAuthorization =

  <P,>(wrappedFunction: GetServerSidePropsHandler<P>) =>

  async (

    _context: GetServerSidePropsContext

  ): Promise<GetServerSidePropsResult<P>> => {

    const store = initializeStore();

    try {

      console.log(

        "Store Access: ",

        store.getState().authentication.accessToken

      );

      const accessToken = await authService.refreshAccessToken();

      console.log("After Request: ", accessToken);

      store.getActions().authentication.setAccessToken(accessToken);

      return {

        redirect: {

          destination: "/",

          permanent: false,

        },

      };

    } catch (e) {

      return wrappedFunction();

    }

  };

Question

  1. What do I need to do to get the build working?

Error Message

2:09:04 PM: info  - Collecting page data...
2:09:05 PM: > Build error occurred
2:09:05 PM: Error: Build optimization failed: found pages without a React Component as default export in
2:09:05 PM: pages/
2:09:05 PM: pages/auth/password/forget
2:09:05 PM: pages/auth/password/reset/[resetToken]
2:09:05 PM: pages/auth/signup
2:09:05 PM: pages/auth/signin
2:09:05 PM: See https://nextjs.org/docs/messages/page-without-valid-component for more info.
2:09:05 PM:     at /opt/build/repo/client/node_modules/next/dist/build/index.js:25:115
2:09:05 PM:     at runMicrotasks (<anonymous>)
2:09:05 PM:     at processTicksAndRejections (internal/process/task_queues.js:97:5)
2:09:05 PM:     at async Span.traceAsyncFn (/opt/build/repo/client/node_modules/next/dist/telemetry/trace/trace.js:6:584)
2:09:06 PM: npm ERR! code ELIFECYCLE
2:09:06 PM: npm ERR! errno 1
2:09:06 PM: npm ERR! client@1.0.0 build: `next build && npm run export`
2:09:06 PM: npm ERR! Exit status 1
2:09:06 PM: npm ERR!
2:09:06 PM: npm ERR! Failed at the client@1.0.0 build script.
2:09:06 PM: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
2:09:06 PM: npm ERR! A complete log of this run can be found in:
2:09:06 PM: npm ERR!     /opt/buildhome/.npm/_logs/2021-05-17T19_09_06_051Z-debug.log

Netlify Config

[build]

base = "client/"

publish = "out/"

command = "npm run build"

[context.production]

environment = {NEXT_PUBLIC_API_URL = "<url>"}

[context.deploy-preview]

environment = {NEXT_PUBLIC_API_URL = "<url>"}

[[headers]]

for = "*.js" # js files should be set this way

[headers.values]

Cache-Control = "public, max-age=604800"

[[headers]]

for = "*.css" # css files too

[headers.values]

Cache-Control = "public, max-age=604800"

[[redirects]]

from = "/*"

status = 200

to = "/index.html"

[[plugins]]

package = "@netlify/plugin-nextjs"

Next.js Config

const withTM = require("next-transpile-modules")(["ky", "ky-universal"]);

module.exports = withTM({

  target: "serverless",

  future: {

    webpack5: true,

  },

  webpack: (config, _options) => {

    config.experiments = {

      topLevelAwait: true,

    };

    return config;

  },

});

Full Deploy Log

2:07:47 PM: Build ready to start
2:07:49 PM: build-image version: 0582042f4fc261adc7bd8333f34884959c577302
2:07:49 PM: build-image tag: v3.7.6
2:07:49 PM: buildbot version: 03c6f9d243f25556225c9548fcb276f97b8bf623
2:07:49 PM: Fetching cached dependencies
2:07:49 PM: Starting to download cache of 163.8MB
2:07:50 PM: Finished downloading cache in 1.108016087s
2:07:50 PM: Starting to extract cache
2:07:56 PM: Finished extracting cache in 5.78936981s
2:07:56 PM: Finished fetching cache in 6.960217013s
2:07:56 PM: Starting to prepare the repo for build
2:07:56 PM: Preparing Git Reference pull/22/head
2:07:57 PM: Parsing package.json dependencies
2:07:59 PM: Different build dir detected, going to use the one specified in the Netlify configuration file: 'client' versus '' in the Netlify UI
2:07:59 PM: Different publish path detected, going to use the one specified in the Netlify configuration file: 'client/out' versus '/' in the Netlify UI
2:07:59 PM: Different build command detected, going to use the one specified in the Netlify configuration file: 'npm run build' versus '' in the Netlify UI
2:07:59 PM: Starting build script
2:07:59 PM: Installing dependencies
2:07:59 PM: Python version set to 2.7
2:07:59 PM: Started restoring cached node version
2:08:02 PM: Finished restoring cached node version
2:08:03 PM: v12.18.0 is already installed.
2:08:04 PM: Now using node v12.18.0 (npm v6.14.4)
2:08:04 PM: Started restoring cached build plugins
2:08:04 PM: Finished restoring cached build plugins
2:08:04 PM: Attempting ruby version 2.7.1, read from environment
2:08:05 PM: Using ruby version 2.7.1
2:08:06 PM: Using PHP version 5.6
2:08:06 PM: Started restoring cached node modules
2:08:06 PM: Finished restoring cached node modules
2:08:06 PM: Started restoring cached go cache
2:08:06 PM: Finished restoring cached go cache
2:08:06 PM: go version go1.14.4 linux/amd64
2:08:06 PM: go version go1.14.4 linux/amd64
2:08:06 PM: Installing missing commands
2:08:06 PM: Verify run directory
2:08:08 PM: ​
2:08:08 PM: ────────────────────────────────────────────────────────────────
2:08:08 PM:   Netlify Build                                                 
2:08:08 PM: ────────────────────────────────────────────────────────────────
2:08:08 PM: ​
2:08:08 PM: ❯ Version
2:08:08 PM:   @netlify/build 11.17.2
2:08:08 PM: ​
2:08:08 PM: ❯ Flags
2:08:08 PM:   deployId: 60a2bf02e19bdd0007f0b632
2:08:08 PM: ​
2:08:08 PM: ❯ Current directory
2:08:08 PM:   /opt/build/repo/client
2:08:08 PM: ​
2:08:08 PM: ❯ Config file
2:08:08 PM:   /opt/build/repo/netlify.toml
2:08:08 PM: ​
2:08:08 PM: ❯ Context
2:08:08 PM:   deploy-preview
2:08:08 PM: ​
2:08:08 PM: ❯ Loading plugins
2:08:08 PM:    - @netlify/plugin-nextjs@3.3.0 from netlify.toml
2:08:09 PM: ​
2:08:09 PM: ────────────────────────────────────────────────────────────────
2:08:09 PM:   1. onPreBuild command from @netlify/plugin-nextjs             
2:08:09 PM: ────────────────────────────────────────────────────────────────
2:08:09 PM: ​
2:08:09 PM: info  - Using webpack 5. Reason: future.webpack5 option enabled https://nextjs.org/docs/messages/webpack5
2:08:10 PM: No Next.js cache to restore.
2:08:10 PM: ​
2:08:10 PM: (@netlify/plugin-nextjs onPreBuild completed in 1s)
2:08:10 PM: ​
2:08:10 PM: ────────────────────────────────────────────────────────────────
2:08:10 PM:   2. build.command from netlify.toml                            
2:08:10 PM: ────────────────────────────────────────────────────────────────
2:08:10 PM: ​
2:08:10 PM: $ npm run build
2:08:10 PM: > client@1.0.0 build /opt/build/repo/client
2:08:10 PM: > next build && npm run export
2:08:11 PM: info  - Using webpack 5. Reason: future.webpack5 option enabled https://nextjs.org/docs/messages/webpack5
2:08:11 PM: warn  - No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
2:08:11 PM: info  - Checking validity of types...
2:08:22 PM: info  - Creating an optimized production build...
2:08:23 PM: info  - Using external babel configuration from /opt/build/repo/client/.babelrc
2:08:58 PM: (node:1327) [DEP_WEBPACK_CHUNK_HAS_ENTRY_MODULE] DeprecationWarning: Chunk.hasEntryModule: Use new ChunkGraph API
2:08:58 PM: (node:1327) [DEP_WEBPACK_CHUNK_ADD_MODULE] DeprecationWarning: Chunk.addModule: Use new ChunkGraph API
2:09:04 PM: warn  - Compiled with warnings
2:09:04 PM: ./node_modules/next/dist/next-server/server/load-components.js
2:09:04 PM: Critical dependency: the request of a dependency is an expression
2:09:04 PM: ./node_modules/next/dist/next-server/server/load-components.js
2:09:04 PM: Critical dependency: the request of a dependency is an expression
2:09:04 PM: ./node_modules/next/dist/next-server/server/load-components.js
2:09:04 PM: Critical dependency: the request of a dependency is an expression
2:09:04 PM: ./node_modules/next/dist/next-server/server/require.js
2:09:04 PM: Critical dependency: the request of a dependency is an expression
2:09:04 PM: ./node_modules/next/dist/next-server/server/require.js
2:09:04 PM: Critical dependency: the request of a dependency is an expression
2:09:04 PM: ./node_modules/next/dist/next-server/server/require.js
2:09:04 PM: Critical dependency: the request of a dependency is an expression
2:09:04 PM: info  - Collecting page data...
2:09:05 PM: > Build error occurred
2:09:05 PM: Error: Build optimization failed: found pages without a React Component as default export in
2:09:05 PM: pages/
2:09:05 PM: pages/auth/password/forget
2:09:05 PM: pages/auth/password/reset/[resetToken]
2:09:05 PM: pages/auth/signup
2:09:05 PM: pages/auth/signin
2:09:05 PM: See https://nextjs.org/docs/messages/page-without-valid-component for more info.
2:09:05 PM:     at /opt/build/repo/client/node_modules/next/dist/build/index.js:25:115
2:09:05 PM:     at runMicrotasks (<anonymous>)
2:09:05 PM:     at processTicksAndRejections (internal/process/task_queues.js:97:5)
2:09:05 PM:     at async Span.traceAsyncFn (/opt/build/repo/client/node_modules/next/dist/telemetry/trace/trace.js:6:584)
2:09:06 PM: npm ERR! code ELIFECYCLE
2:09:06 PM: npm ERR! errno 1
2:09:06 PM: npm ERR! client@1.0.0 build: `next build && npm run export`
2:09:06 PM: npm ERR! Exit status 1
2:09:06 PM: npm ERR!
2:09:06 PM: npm ERR! Failed at the client@1.0.0 build script.
2:09:06 PM: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
2:09:06 PM: npm ERR! A complete log of this run can be found in:
2:09:06 PM: npm ERR!     /opt/buildhome/.npm/_logs/2021-05-17T19_09_06_051Z-debug.log
2:09:06 PM: ​
2:09:06 PM: ────────────────────────────────────────────────────────────────
2:09:06 PM:   "build.command" failed                                        
2:09:06 PM: ────────────────────────────────────────────────────────────────
2:09:06 PM: ​
2:09:06 PM:   Error message
2:09:06 PM:   Command failed with exit code 1: npm run build
2:09:06 PM: ​
2:09:06 PM:   Error location
2:09:06 PM:   In build.command from netlify.toml:
2:09:06 PM:   npm run build
2:09:06 PM: ​
2:09:06 PM:   Resolved config
2:09:06 PM:   build:
2:09:06 PM:     base: /opt/build/repo/client
2:09:06 PM:     command: npm run build
2:09:06 PM:     commandOrigin: config
2:09:06 PM:     environment:
2:09:06 PM:       - REVIEW_ID
2:09:06 PM:       - NEXT_PUBLIC_API_URL
2:09:06 PM:     publish: /opt/build/repo/client/out
2:09:06 PM:   headers:
2:09:06 PM:     - for: '*.js'
2:09:06 PM:       values:
2:09:06 PM:         Cache-Control: public, max-age=604800
2:09:06 PM:     - for: '*.css'
2:09:06 PM:       values:
2:09:06 PM:         Cache-Control: public, max-age=604800
2:09:06 PM:   plugins:
2:09:06 PM:     - inputs: {}
2:09:06 PM:       origin: config
2:09:06 PM:       package: '@netlify/plugin-nextjs'
2:09:06 PM:   redirects:
2:09:06 PM:     - from: /*      status: 200      to: /index.htmlCaching artifacts
2:09:06 PM: Started saving node modules
2:09:06 PM: Finished saving node modules
2:09:06 PM: Started saving build plugins
2:09:06 PM: Finished saving build plugins
2:09:06 PM: Started saving pip cache
2:09:06 PM: Finished saving pip cache
2:09:06 PM: Started saving emacs cask dependencies
2:09:06 PM: Finished saving emacs cask dependencies
2:09:06 PM: Started saving maven dependencies
2:09:06 PM: Finished saving maven dependencies
2:09:06 PM: Started saving boot dependencies
2:09:06 PM: Finished saving boot dependencies
2:09:06 PM: Started saving rust rustup cache
2:09:06 PM: Finished saving rust rustup cache
2:09:06 PM: Started saving go dependencies
2:09:06 PM: Finished saving go dependencies
2:09:06 PM: Build failed due to a user error: Build script returned non-zero exit code: 2
2:09:06 PM: Creating deploy upload records
2:09:06 PM: Failing build: Failed to build site
2:09:06 PM: Failed during stage 'building site': Build script returned non-zero exit code: 2
2:09:06 PM: Finished processing build request in 1m17.838557716s

Thank you for the help!

Hey Luis,

Unfortunately, the best I can do is share the specific error from the log:

https://app.netlify.com/sites/epic-mcclintock-39b7aa/deploys/60a48bcc4fbe5800089d8331#L97-L108

That refers us to a Next error message: page-without-valid-component | Next.js

There’s some good info in the message, suggesting that you check whether the erroneous pages are meant to be components or double-checking that the returned value for the page after export default is that of a valid component.

If issues persist, given that this is an out-and-out Next build failure, you may want to reach out to their team!

1 Like

Thanks for responding Pie! As I mentioned in the post, I don’t think it’s actually that error because, code otherwise untouched, when I make the target in the next.config file not ‘serverless’ and thus disable the plugin. It works perfectly, the build goes through just fine.

Do you know much about how the Next Netlify Plugin works?

Also doesn’t this have a default export?

import { SignIn } from "../../Registration/SignIn/SignIn";
import {
  withoutAuthorization,
  withoutServerSideAuthorization,
} from "../../HOCs/authorization.hocs";

export default withoutAuthorization(SignIn);

export const getServerSideProps = withoutServerSideAuthorization(() => {
  return { props: {} };
});

But as you can see from the logs, it still thinks that it doesn’t have a default export

So upon further investigation I was able to narrow down the issue even further. For some reason using HOCs as you normally do (export default HOC(Component). Makes the plugin glitch out.

This is how that component looks like:

function withoutAuthorization<T>(
  WrappedComponent: React.ComponentType<T>
): React.ComponentType<T> {

const UnauthorizedComponent: React.FC<T> = (props) => {
     const router = useRouter();
     const { accessToken, userId } = useStoreState(
            (state) => state.authentication
     );
    const companyId = useStoreState(
       (state) => state.user.userById[userId]
     )?.companyId;

const isInBrowser = typeof window !== "undefined";

if (isInBrowser && accessToken) {
  if (!companyId) {
    router.push("/auth/onboarding");
  } else {
    router.push("/");
  }
}

     return <WrappedComponent {...props} />;
  };
  return UnauthorizedComponent;
}

Edit:
Actually even just importing the HOC, without actually using it will cause problems. Which is really weird.

So just doing this will cause that page found with no default exports error:

import { } from "../../HOCs/authorization.hocs";

Interesting! And a great find. I’d definitely suggest letting the plugin team know about this, whether it’s a considered caveat, by design or otherwise worth noting!

1 Like

Yeah drilling down it seems to be something I’m defining in the Redux store file is having strange issues with the plugin.

Just so I know how to explain it in a way that makes sense, how should I phrase it to them? Its a complicated enough issue that I’m struggling with finding an easy phrasing for it

Just to be clear, this is the store definition that’s causing the problem. I’ve removed a lot of the previous complexity to try to hone down on the issue at hand.

import {

  createStore,

  createTypedHooks,

  EasyPeasyConfig,

  Store,

} from "easy-peasy";

import { Injections, services } from "./injections";

import { checkTokenExpiration } from "./middleware/checkTokenExpiration";

import { StoreInitialState, StoreModel, storeModel } from "./models";

const { useStoreActions, useStoreDispatch, useStoreState } =

  createTypedHooks<StoreModel>();

export let store: Store<

  StoreModel,

  EasyPeasyConfig<StoreInitialState, Injections>

> = createStore<StoreModel, StoreInitialState, Injections>(storeModel, {

  injections: {

    ...services,

  },

  middleware: [checkTokenExpiration],

});

The easiest thing to do, and most beneficial to the team would be to:

  • create the smallest repro possible that the team can access
  • share the build log failure from this repro site
  • a public repo, if possible, would be a great plus!
2 Likes

Yup I’m working on that right now!

@Pie So here’s a repo replicating the error with as minimal effort as possible. GitHub - LuisOsta/blog-starter-typescript-app

I’ve actually dug even deeper and it seems that its neither and issue with the store or the HOCs. But of a package called ky-universal. A popular alternative to axios.

Just importing it will cause that error. Which is very strange and I’m unsure as to why it happens. I think this is actually an error with either ky or Next.js and not something that is wrong with the plugin.

I was able to reproduce the bug locally by using next build instead of export. Which explains why it worked on Netlify without the plugin. As the plugin, I believe, uses next build

So for whoever poor soul is reading this in the future. Either just migrate back to axios or use these versions of Ky

 "ky": "0.25.1",
 "ky-universal": "0.8.2"

There is still a problem that Next.js was providing the wrong error message. But this should resolve the problem.

3 Likes

Thanks for circling back and updating this thread, @LuisOsta! This will definitely be beneficial to future Forums members who encounter something similar :netliconfetti:

1 Like