formio / react

JSON powered forms for React.js

Home Page:https://form.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"window is not defined" error in Next.js 14

Matthew-owo opened this issue · comments

I'm trying to use formio in next js, but I get the following error, but the form seems to render successfully.
Am I using formio correctly? Or does formio not support next js?

Sample Code:

"use client";
import { Form } from "@formio/react";

const Page = () => {
  return (
    <>
      <Form src="https://examples.form.io/example" />
    </>
  );
};

export default Page;

Terminal:

 ⨯ node_modules\formiojs\providers\storage\s3.js (54:22) @ window
 ⨯ ReferenceError: window is not defined
    at __webpack_require__ (C:\Users\user\development\my-app\.next\server\webpack-runtime.js:33:43)
    at __webpack_require__ (C:\Users\user\development\my-app\.next\server\webpack-runtime.js:33:43)
    at __webpack_require__ (C:\Users\user\development\my-app\.next\server\webpack-runtime.js:33:43)
    at __webpack_require__ (C:\Users\user\development\my-app\.next\server\webpack-runtime.js:33:43)
    at __webpack_require__ (C:\Users\user\development\my-app\.next\server\webpack-runtime.js:33:43)
    at __webpack_require__ (C:\Users\user\development\my-app\.next\server\webpack-runtime.js:33:43)
    at __webpack_require__ (C:\Users\user\development\my-app\.next\server\webpack-runtime.js:33:43)
    at __webpack_require__ (C:\Users\user\development\my-app\.next\server\webpack-runtime.js:33:43)
    at __webpack_require__ (C:\Users\user\development\my-app\.next\server\webpack-runtime.js:33:43)
    at __webpack_require__ (C:\Users\user\development\my-app\.next\server\webpack-runtime.js:33:43)
    at eval (./src/app/formioreact/page.tsx:7:71)
    at (ssr)/./src/app/formioreact/page.tsx (C:\Users\user\development\my-app\.next\server\app\formioreact\page.js:228:1)
    at __webpack_require__ (C:\Users\user\development\my-app\.next\server\webpack-runtime.js:33:43)
    at JSON.parse (<anonymous>)
null

package.json

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@formio/js": "^5.0.0-rc.37",
    "@formio/react": "^5.3.0",
    "formiojs": "^4.18.0",
    "next": "14.0.4",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "eslint": "^8",
    "eslint-config-next": "14.0.4",
    "typescript": "^5"
  }
}

I have a basic setup of the app recommended in the documentation and facing a similar issue while building the NextJs React app.

Build error occurred
ReferenceError: window is not defined
at Object. (/app/node_modules/formiojs/providers/storage/s3.js:54:23)
at Module._compile (node:internal/modules/cjs/loader:1198:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1252:10)
at Module.load (node:internal/modules/cjs/loader:1076:32)
at Function.Module._load (node:internal/modules/cjs/loader:911:12)
at Module.require (node:internal/modules/cjs/loader:1100:19)
at require (node:internal/modules/cjs/helpers:119:18)
at Object. (/app/node_modules/formiojs/providers/storage/index.js:9:33)
at Module._compile (node:internal/modules/cjs/loader:1198:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1252:10) {
type: 'ReferenceError'

Hey guys @viralP1 @Matthew-owo I am currently working on this issue, but please help me understand something: does this issue get resolved with a regular old check for window? In other words, because Form.io is currently a client-side rendering engine, if you change your component to something like this:

const Page = () => {
  return (
    <>
      typeof window === 'undefined' ? null : <Form src="https://examples.form.io/example" />
    </>
  );
};

does it work? Or does it still not like the actual imports of Form.io? FWIW I believe this is the recommended approach for client components with client-side-only code.

Yes @brendanbond the approach you suggested is the typical way to handle Client Side Rendering (CSR) in the next.js. I implemented that solution in my project but it didn't work for me.

This is another approach I found:
import dynamic from 'next/dynamic' const Form = dynamic(() => import('@formio/react').then(module => module.Form), { ssr: false })

Now you can use the Form object as you need

Any update on this? there are still issues rendering in nextjs (e.g. choice.js not working because of this dynamic load)