jakezatecky/react-dual-listbox

Component does not play nicely with Server Side Rendering (SSR)

Closed this issue · 4 comments

Describe the bug
After updating the package to v6.0.0 I am seeing error below in the terminal and the app is crashing because of it.

error:

⨯ node_modules/react-dual-listbox/lib/index.js (2541:0) @ Array.<anonymous> ⨯ ReferenceError: Element is not defined at Array.<anonymous> (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:1896:95) at __webpack_require__ (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:3852:51) at Array.hasOwn (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:957:90) at __webpack_require__ (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:3852:51) at Array.<anonymous> (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:859:86) at __webpack_require__ (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:3852:51) at Array.<anonymous> (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:30:104) at __webpack_require__ (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:3852:51) at /Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:3903:92 at /Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:3905:11 at /Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:3907:16 at webpackUniversalModuleDefinition (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:10:85) at Object.<anonymous> (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/node_modules_react-dual-listbox_lib_index_77fd12.js:14:3) at instantiateModule (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:452:23) at getOrInstantiateModuleFromParent (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:502:12) at esmImport (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:110:20) at /Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/src_15f6da._.js:1392:153 at [project]/src/components/dual-lisbox/dual-listbox.tsx [ssr] (ecmascript) (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/src_15f6da._.js:1508:3) at instantiateModule (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:452:23) at getOrInstantiateModuleFromParent (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:502:12) at esmImport (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:110:20) at /Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/src_15f6da._.js:1745:152 at [project]/src/app/admin/back-tester/components/common-fields.tsx [ssr] (ecmascript) (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/src_15f6da._.js:1989:3) at instantiateModule (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:452:23) at getOrInstantiateModuleFromParent (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:502:12) at esmImport (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:110:20) at /Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/src_15f6da._.js:2000:169 at [project]/src/app/admin/back-tester/components/form.tsx [ssr] (ecmascript) (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/src_15f6da._.js:2341:3) at instantiateModule (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:452:23) at getOrInstantiateModuleFromParent (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:502:12) at esmImport (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:110:20) at /Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/src_15f6da._.js:3188:157 at [project]/src/app/admin/back-tester/page.tsx [ssr] (ecmascript) (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/src_15f6da._.js:3284:3) at instantiateModule (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:452:23) at getOrInstantiateModuleFromParent (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:502:12) at commonJsRequire (/Users/mariamk/Desktop/front-admin-modern/.next/server/chunks/[turbopack]_runtime.js:124:20)

Reproduction steps
update to version 6.0.0

Expected behavior
update without errors

I spent a couple of hours troubleshooting your issue. I confirmed it is a Next.js issue (and not a Node/ESM/Webpack issue).

The issue results from Next.js defaulting to using Server Side Rendering (SSR). That is problematic for a number of reasons, but in this case the DualListBox component uses Element (a DOM class) in the transpiled code, which is inaccessible when using SSR.

When using Next.js, you can overcome this limitation by using so-called dynamic imports:

import dynamic from 'next/dynamic';

const DualListBox = dynamic(() => import('react-dual-listbox'), { ssr: false });

I have tried using dynamic import, and the error that I see changed (attaching logs below). Here is my package json:

{
	"name": "admin",
	"version": "0.1.0",
	"private": true,
	"scripts": {
		"dev": "next dev --turbo",
		"build": "next build",
		"start": "next start",
		"lint": "next lint",
		"format": "prettier --check --ignore-path .gitignore .",
		"format:fix": "prettier --write --ignore-path .gitignore ."
	},
	"dependencies": {
		"@faker-js/faker": "^8.2.0",
		"@hookform/resolvers": "^3.3.2",
		"@radix-ui/react-avatar": "^1.0.4",
		"@radix-ui/react-checkbox": "^1.0.4",
		"@radix-ui/react-dialog": "^1.0.5",
		"@radix-ui/react-dropdown-menu": "^2.0.6",
		"@radix-ui/react-icons": "^1.3.0",
		"@radix-ui/react-label": "^2.0.2",
		"@radix-ui/react-popover": "^1.0.7",
		"@radix-ui/react-radio-group": "^1.1.3",
		"@radix-ui/react-scroll-area": "^1.0.5",
		"@radix-ui/react-select": "^2.0.0",
		"@radix-ui/react-separator": "^1.0.3",
		"@radix-ui/react-slider": "^1.1.2",
		"@radix-ui/react-slot": "^1.0.2",
		"@radix-ui/react-switch": "^1.0.3",
		"@radix-ui/react-tabs": "^1.0.4",
		"@radix-ui/react-toast": "^1.1.5",
		"@radix-ui/react-tooltip": "^1.0.7",
		"@t3-oss/env-nextjs": "^0.7.1",
		"@tanstack/react-table": "^8.10.7",
		"@typescript-eslint/eslint-plugin": "^6.9.1",
		"class-variance-authority": "^0.7.0",
		"clsx": "^2.0.0",
		"cmdk": "^0.2.0",
		"date-fns": "^2.30.0",
		"eslint-config-airbnb": "^19.0.4",
		"eslint-config-prettier": "^9.0.0",
		"eslint-plugin-prettier": "^5.0.1",
		"eslint-plugin-sonarjs": "^0.21.0",
		"lucide-react": "^0.291.0",
		"next": "^14.0.3",
		"next-auth": "^4.24.5",
		"next-themes": "^0.2.1",
		"prettier": "^3.0.3",
		"react": "^18.2.0",
		"react-day-picker": "^8.9.1",
		"react-dom": "^18.2.0",
		"react-dual-listbox": "^6.0.0",
		"react-hook-form": "^7.48.2",
		"react-wrap-balancer": "^1.1.0",
		"sass": "^1.69.4",
		"tailwind-merge": "^2.0.0",
		"tailwindcss-animate": "^1.0.7",
		"vaul": "^0.7.7",
		"zod": "^3.22.4"
	},
	"devDependencies": {
		"@trivago/prettier-plugin-sort-imports": "^4.3.0",
		"@types/node": "^20.8.10",
		"@types/react": "^18",
		"@types/react-dom": "^18",
		"@types/react-dual-listbox": "^2.2.5",
		"autoprefixer": "^10",
		"eslint": "^8",
		"eslint-config-next": "^14.0.1",
		"postcss": "^8",
		"tailwindcss": "^3",
		"typescript": "^5"
	}
}

localhost-1703833780464.log
localhost-1703833797619.log
localhost-1703833805819.log
localhost-1703833810909.log
localhost-1703833817700.log
localhost-1703833821847.log
localhost-1703833826532.log
localhost-1703833832431.log
localhost-1703833840733.log
localhost-1703833846336.log
localhost-1703833850133.log
localhost-1703833854969.log

I went ahead and made a type check that should ensure compatibility with server side rendering. This should resolve issues with the default configuration of NextJS and any other similar framework.