mantinedev / mantine

A fully featured React components library
https://mantine.dev
MIT License
26.79k stars 1.9k forks source link

Textarea breaking SSR? #6719

Closed xorander00 closed 2 months ago

xorander00 commented 2 months ago

Dependencies check up

What version of @mantine/* packages do you have in package.json?

7.12.1

What package has an issue?

@mantine/core

What framework do you use?

Remix

In which browsers you can reproduce the issue?

Not applicable – issue is not related to the browser

Describe the bug

Not sure if I'm missing something, but it seems that the Textarea component is trying to access the DOM without checking for it first? I'm deploying my small Remix app to Netlify Edge Functions. The Netlify automated build process throws an error (see log output below, towards the bottom at "ReferenceError: document is not defined").

When I remove the Textarea component, Netilfy builds and deploys it fine. I haven't yet dug into the source as I'm tight on time, but if it's something dumb on my side, then my apologies :) Didn't find any warnings/caveats in the docs regarding this behavior though.

Oh yeah, and the Textarea component only has the placeholder prop set, along with styles. I tried changing from styles to classNames, but that didn't make a difference either.

12:22:33 PM: Netlify Build                                                 
12:22:33 PM: ────────────────────────────────────────────────────────────────
12:22:33 PM: ​
12:22:33 PM: ❯ Version
12:22:33 PM:   @netlify/build 29.54.0
12:22:33 PM: ​
12:22:33 PM: ❯ Flags
12:22:33 PM:   accountId: 65ee6d4c918431e4d1d5e45c
12:22:33 PM:   baseRelDir: true
12:22:33 PM:   buildId: 66cb5a1882949c0008aea53d
12:22:33 PM:   deployId: 66cb5a1882949c0008aea53f
12:22:34 PM: ​
12:22:34 PM: ❯ Current directory
12:22:34 PM:   /opt/build/repo
12:22:34 PM: ​
12:22:34 PM: ❯ Config file
12:22:34 PM:   /opt/build/repo/netlify.toml
12:22:34 PM: ​
12:22:34 PM: ❯ Context
12:22:34 PM:   production
12:22:34 PM: ​
12:22:34 PM: build.command from netlify.toml                               
12:22:34 PM: ────────────────────────────────────────────────────────────────
12:22:34 PM: ​
12:22:34 PM: $ npm run build
12:22:34 PM: > build
12:22:34 PM: > remix vite:build
12:22:34 PM: vite v5.4.2 building for production...
12:22:34 PM: transforming...
12:22:37 PM: ✓ 850 modules transformed.
12:22:37 PM: Generated an empty chunk: "admin".
12:22:37 PM: rendering chunks...
12:22:37 PM: computing gzip size...
12:22:37 PM: build/client/.vite/manifest.json                          4.50 kB │ gzip:  0.74 kB
12:22:37 PM: build/client/assets/home-we-do-icon-4-D66IsIJp.png        7.02 kB
12:22:37 PM: build/client/assets/home-we-do-icon-1-DT6H2cKd.png        8.28 kB
12:22:37 PM: build/client/assets/home-we-do-icon-5-CUHTSOWD.png        9.24 kB
12:22:37 PM: build/client/assets/home-we-do-icon-2-CeSkuWfp.png       10.18 kB
12:22:37 PM: build/client/assets/home-we-do-icon-3-DtptWONi.png       13.20 kB
12:22:37 PM: build/client/assets/home-how-we-work-tags--eCf_AMe.png   49.51 kB
12:22:37 PM: build/client/assets/wood-light-720x652-eNBXNkzu.png     252.22 kB
12:22:37 PM: build/client/assets/_index-CuO1MhI1.css                   1.63 kB │ gzip:  0.48 kB
12:22:37 PM: build/client/assets/root-CaJrguJE.css                   238.15 kB │ gzip: 39.42 kB
12:22:37 PM: build/client/assets/admin-l0sNRNKZ.js                     0.00 kB │ gzip:  0.02 kB
12:22:37 PM: build/client/assets/what-we-do-DiYmRQe1.js                0.17 kB │ gzip:  0.16 kB
12:22:37 PM: build/client/assets/who-we-are-B0OOHl7Z.js                0.17 kB │ gzip:  0.16 kB
12:22:37 PM: build/client/assets/how-we-work-C7LIzqLW.js               0.17 kB │ gzip:  0.16 kB
12:22:37 PM: build/client/assets/lets-connect-B5e63KVE.js              0.17 kB │ gzip:  0.16 kB
12:22:37 PM: build/client/assets/entry.client-CBCvRtJB.js              4.06 kB │ gzip:  1.54 kB
12:22:37 PM: build/client/assets/jsx-runtime-BMrMXMSG.js               8.12 kB │ gzip:  3.05 kB
12:22:37 PM: build/client/assets/Stack-lVN7Yn3e.js                    10.28 kB │ gzip:  3.18 kB
12:22:37 PM: build/client/assets/Title-DbweaZo4.js                    27.88 kB │ gzip:  9.15 kB
12:22:37 PM: build/client/assets/root-Bey2O7Jx.js                    132.17 kB │ gzip: 46.96 kB
12:22:37 PM: build/client/assets/_index-uLCJW_J3.js                  136.80 kB │ gzip: 48.52 kB
12:22:37 PM: build/client/assets/components-BvaqjdmS.js              244.58 kB │ gzip: 78.97 kB
12:22:37 PM: ✓ built in 2.83s
12:22:37 PM: vite v5.4.2 building SSR bundle for production...
12:22:37 PM: transforming...
12:22:39 PM: ✓ 856 modules transformed.
12:22:39 PM: rendering chunks...
12:22:40 PM: build/server/.vite/manifest.json                            2.08 kB
12:22:40 PM: build/server/assets/home-we-do-icon-4-D66IsIJp.png          7.02 kB
12:22:40 PM: build/server/assets/home-we-do-icon-1-DT6H2cKd.png          8.28 kB
12:22:40 PM: build/server/assets/home-we-do-icon-5-CUHTSOWD.png          9.24 kB
12:22:40 PM: build/server/assets/home-we-do-icon-2-CeSkuWfp.png         10.18 kB
12:22:40 PM: build/server/assets/home-we-do-icon-3-DtptWONi.png         13.20 kB
12:22:40 PM: build/server/assets/home-how-we-work-tags--eCf_AMe.png     49.51 kB
12:22:40 PM: build/server/assets/wood-light-720x652-eNBXNkzu.png       252.22 kB
12:22:40 PM: build/server/assets/server-build-yYDhNZTu.css             239.78 kB
12:22:40 PM: build/server/index.js                                       0.25 kB
12:22:40 PM: build/server/server.js                                     57.08 kB
12:22:40 PM: build/server/assets/server-build-hMvCN6KG.js            1,014.63 kB
12:22:40 PM: ✓ 1 asset moved from Remix server build to client assets.
12:22:40 PM: build/client/assets/server-build-yYDhNZTu.css
12:22:40 PM: ✓ built in 2.39s
12:22:40 PM: ​
12:22:40 PM: (build.command completed in 6s)
12:22:40 PM: ​
12:22:40 PM: Edge Functions bundling                                       
12:22:40 PM: ────────────────────────────────────────────────────────────────
12:22:40 PM: ​
12:22:40 PM: Packaging Edge Functions from .netlify/edge-functions directory:
12:22:40 PM:  - remix-server
12:22:41 PM: ReferenceError: document is not defined
12:22:41 PM:     at file:///opt/build/repo/build/server/assets/server-build-hMvCN6KG.js:22673:12
12:22:41 PM: ​
12:22:41 PM: Bundling of edge function failed                              
12:22:41 PM: ────────────────────────────────────────────────────────────────
12:22:41 PM: ​
12:22:41 PM:   Error message
12:22:41 PM:   Could not load edge function at '/opt/build/repo/.netlify/edge-functions/remix-server.mjs'. More on the Edge Functions API at https://ntl.fyi/edge-api.
12:22:41 PM: ​
12:22:41 PM:   Error location
12:22:41 PM:   While bundling edge function

If possible, include a link to a codesandbox with a minimal reproduction

No response

Possible fix

If Textarea is trying to access the DOM document object, then add a check condition before it tries to do so?

Self-service

rtivital commented 2 months ago

Textarea component works fine with ssr. Mantine documentation is built with Next.js that server side rendering, on the documentation page there are no issues https://mantine.dev/core/textarea/

xorander00 commented 2 months ago

It's an issue with react-textarea-autoresize that Textarea uses and, apparently, it's an issue for edge runtimes in general. I'm going to try configuring serverBuildTarget and deploying again to see if it works. If not, then I'll try the hack proposed in https://github.com/Andarist/react-textarea-autosize/issues/335#issuecomment-1556061728. It might be worth noting in the docs if anyone else deploying to edge runs into this issue. Will confirm whether or it fixes the issue or not.

xorander00 commented 2 months ago

Got it to work, but it's kind of hacky. I haven't yet figured out the Vite config for the right runtime target + module format to support Edge Functions. So I ended up using vite-env-only plugin and its clientOnly$ macro to conditionally render the Textarea so that it's client-only. Not great, but it works. Ideally it wouldn't require that and would instead bundle for the provider target runtime and module format (e.g. netlify, vercel, deno, cloudflare, etc). I'm not sure yet whether it's something that should be addressed in react-textarea-autosize or whether it should just be documented as a caveat for deploying to Edge runtimes, but it's something to be aware of as I'm sure it's not an uncommon scenario.

Basically, it went from...

import { Textarea } from '@mantine/core';

// ...

export function MyComponent() {
  return (
    <Textarea placeholder="message" />
  );
}

...to...

import { Textarea } from '@mantine/core';
import { clientOnly$ } from 'vite-env-only/macros';

// ...

export function MyComponent() {
  return (
    {clientOnly$(<Textarea placeholder="message" />)}
  );
}

@rtivital Do you think it's worth evaluating replacements for react-textarea-autosize? I'm neutral either way and not sure if it's worth it, but can't say for sure that it isn't. I'd be willing to try it out as soon as I get some free time. Though if you think it's not really worth it, then I'd be less inclined to waste my time. https://github.com/inokawa/rich-textarea looks interesting.

Leaving this here for anyone in the future that might find this information helpful.

EDIT: Adding that https://github.com/dai-shi/waku/issues/421 contains a lot of good info regarding react-textarea-autosize and importing the proper module.

rtivital commented 2 months ago

I'd rather not migrate it to anything else. Once field-size CSS property is supported, react-textarea-autosize dependency will be removed – https://caniuse.com/mdn-css_properties_field-sizing

rtivital commented 2 months ago

The issue is related to waku, won't be fixed on Mantine side.