react-spectrum icon indicating copy to clipboard operation
react-spectrum copied to clipboard

[@react-aria/live-announcer] "Uncaught Error: document is not defined" when used in render function in SSR

Open wojtekmaj opened this issue 1 year ago โ€ข 1 comments

Provide a general summary of the issue here

When announce() is used in render function in SSR, it triggers an error: "Uncaught Error: document is not defined".

๐Ÿค” Expected Behavior?

announce() to abort if document is not defined

๐Ÿ˜ฏ Current Behavior

announce() attempts to create div using document.createElement even in Node.js environment

๐Ÿ’ Possible Solution

if (typeof document === 'undefined') {
  return;
}

๐Ÿ”ฆ Context

No response

๐Ÿ–ฅ๏ธ Steps to Reproduce

Run the following component in SSR:

function Search() {
  const searchParams = useSearchParams();
  const [searchQuery, setSearchQuery] = useState(searchParams.get('search'));

  const results = use(getResults());

  searchQuery && announce(`Found ${results.length} results`, 'polite');

  return <></>;
}

Version

3.34.1

What browsers are you seeing the problem on?

Other

If other, please specify.

Node.js

What operating system are you using?

macOS Ventura

๐Ÿงข Your Company/Team

No response

๐Ÿ•ท Tracking Issue

No response

wojtekmaj avatar Apr 19 '24 08:04 wojtekmaj

Thanks for the issue!

I don't think you should use an announce in the render function, it has a side effect. I think you should put it inside an effect which wouldn't run on the server anyways. That, or put it in an interaction callback.

In addition, you may have this announced more times than you expect because you're relying on renders, which are not guaranteed and in React 18+ may actually run multiple times in their concurrent model. In an effect you can guard against extraneous calls.

snowystinger avatar Apr 22 '24 01:04 snowystinger