10

I know this question has been asked multiple times before but none of the solution seems to work.

I'm trying to use the library 'react-chat-popup' which only renders on client side in a SSR app.(built using next.js framework) The normal way to use this library is to call import {Chat} from 'react-chat-popup' and then render it directly as <Chat/>.

The solution I have found for SSR apps is to check if typedef of window !=== 'undefined' in the componentDidMount method before dynamically importing the library as importing the library normally alone would already cause the window is not defined error. So I found the link https://github.com/zeit/next.js/issues/2940 which suggested the following:

Chat = dynamic(import('react-chat-popup').then(m => {
  const {Foo} = m;
  Foo.__webpackChunkName = m.__webpackChunkName;
  return Foo;
}));

However, my foo object becomes null when I do this. When I print out the m object in the callback, i get {"__webpackChunkName":"react_chat_popup_6445a148970fe64a2d707d15c41abb03"} How do I properly import the library and start using the <Chat/> element in this case?

Lew Wei Hao
  • 763
  • 1
  • 13
  • 25

3 Answers3

13

Next js now has its own way of doing dynamic imports with no SSR.

import dynamic from 'next/dynamic'

const DynamicComponentWithNoSSR = dynamic(
  () => import('../components/hello3'),
  { ssr: false }
)

Here is the link of their docs: next js

Adrian Gonzalez
  • 737
  • 1
  • 7
  • 20
10

I've managed to resolve this by first declaring a variable at the top:

let Chat = ''

then doing the import this way in componentDidMount:

async componentDidMount(){
        let result = await import('react-chat-popup')
        Chat = result.Chat
        this.setState({
            appIsMounted: true
        })
    }

and finally render it like this:

<NoSSR>
   {this.state.appIsMounted? <Chat/> : null}
</NoSSR>
Lew Wei Hao
  • 763
  • 1
  • 13
  • 25
  • It feels like the react-chat-popup is working horribly wrong with SSR if it requires such a hack to work, but good job for finding the solution! – Obed Parlapiano Aug 11 '18 at 15:17
  • Check my answer for a native way to solve this. – Adrian Gonzalez Dec 17 '21 at 16:27
  • I had to convert the Home function into a class that extends React.Component to make this work. Thanks for this! – Bugs Bunny Jul 19 '22 at 11:16
  • @AdrianGonzalez your solution doesn't solve this natively for any external dependencies, only for relative dependencies. [Next.js even provides an alternative when dynamically importing non-components](https://nextjs.org/docs/advanced-features/dynamic-import#with-external-libraries), though there's no sample for external library components. – bsplosion Jan 31 '23 at 22:29
-1

You may not always want to include a module on server-side. For example, when the module includes a library that only works in the browser.

Import the library normally in child component and import that component dynamically on parent component.

https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr

This approach worked for me.