"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)