'NextJS - ReactDOMServer does not yet support Suspense

I'm currently trying to incorporate a loader component to a site built with NextJS. I would like to use Suspense to show a loading screen may it be after refreshing the page or changing routes. This is how my code goes:

import Head from 'next/head'
import { Loader } from '../components/loader'
const { Suspense } = require('React')

function MyApp({ Component, pageProps }) {
   return (
   <>
     <Suspense fallback={<Loader />}>
        <Head>
         .... some codes such as meta tags, title tags ....
        </Head>
      <Component {...pageProps} />;
      </Suspense>
   </>
   )
}

My problem is I get an error that says ReactDOMServer does not yet support Suspense. but I would like to use Suspense to enable a loading screen on my page. Much like this website



Solution 1:[1]

You can use React 18 features like suspense in Next.js Advanced Features. Obviously it's still experimental and might cause issues with you application.

npm install next@latest react@rc react-dom@rc

To enable, use the experimental flag concurrentFeatures: true

// next.config.js
module.exports = {
  experimental: {
    concurrentFeatures: true,
  },
}

Once enabled, you can use Suspense and SSR streaming for all pages.

import dynamic from 'next/dynamic'
import { lazy, Suspense } from 'react'

import Content from '../components/content'

// These two ways are identical:
const Profile = dynamic(() => import('./profile'), { suspense: true })
const Footer = lazy(() => import('./footer'))

export default function Home() {
  return (
    <div>
      <Suspense fallback={<Spinner />}>
        {/* A component that uses Suspense-based */}
        <Content />
      </Suspense>
      <Suspense fallback={<Spinner />}>
        <Profile />
      </Suspense>
      <Suspense fallback={<Spinner />}>
        <Footer />
      </Suspense>
    </div>
  )
}

Solution 2:[2]

I had a similar issue. I ended up simulating the Suspense with a combination of setState & componentDidMount

render(){
    return this.state.browser ? <Component/> : <Placeholder/>
}

componentDidMount(){
    this.setState({browser: true})
}

I hope it helps.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tom Wicks
Solution 2 TapMeppe