next.js: Getting ReactDOMServer does not yet support Suspense error while using styled-components

What version of Next.js are you using?

10.0.6

What version of Node.js are you using?

14.4.0

What browser are you using?

Firefox

What operating system are you using?

Mac

How are you deploying your application?

Heroku

Describe the Bug

I recently updated next-i18next to 8.0.0 and am also using styled components with a custom _document.js as described in the nextjs examples section (https://github.com/vercel/next.js/tree/master/examples/with-styled-components).

If I load my page index and navigate to another page like /about, everything works fine. If I try to navigate directly to /about, I get the following error: Error: ReactDOMServer does not yet support Suspense.

Expected Behavior

I would expect to be able to load other pages directly without an error appearing.

To Reproduce

Code snippets below in the comments.

The error I’m getting is: Error: ReactDOMServer does not yet support Suspense.

Screen Shot 2021-02-24 at 12 34 34 PM

Here’s an example of _document.js

import React from 'react';
import PropTypes from 'prop-types';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheet as StyledComponentsSheet } from 'styled-components';
import { ServerStyleSheets as MaterialUiSheets } from '@material-ui/core/styles';

const { NEXT_PUBLIC_GA_TRACKING_ID } = process.env;

const propTypes = {
    lang: PropTypes.string,
};

const defaultProps = {
    lang: 'en',
};

class MyDocument extends Document {
    static async getInitialProps(ctx) {
        const styledComponentsSheet = new StyledComponentsSheet();
        const materialUiSheets = new MaterialUiSheets();
        const originalRenderPage = ctx.renderPage;

        try {
            ctx.renderPage = () =>
                originalRenderPage({
                    enhanceApp: (App) => (props) =>
                        styledComponentsSheet.collectStyles(
                            materialUiSheets.collect(<App {...props} />),
                        ),
                });

            const initialProps = await Document.getInitialProps(ctx);

            return {
                ...initialProps,
                styles: [
                    <React.Fragment key='styles'>
                        {initialProps.styles}
                        {materialUiSheets.getStyleElement()}
                        {styledComponentsSheet.getStyleElement()}
                    </React.Fragment>,
                ],
            };
        } finally {
            styledComponentsSheet.seal();
        }
    }

    render() {
        const { lang } = this.props;

        return (
            <Html lang={lang}>
                <Head>
                    <script
                        async
                        src={`https://www.googletagmanager.com/gtag/js?id=${NEXT_PUBLIC_GA_TRACKING_ID}`}
                    />
                    <script
                        async
                        src='https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'
                    />
                    <script
                        dangerouslySetInnerHTML={{
                            __html: `window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);} gtag('js',new Date());gtag('config','${NEXT_PUBLIC_GA_TRACKING_ID}',{page_path:window.location.pathname,});`,
                        }}
                    />
                </Head>
                <body>
                    <Main />
                    <NextScript />
                    <script> </script>
                </body>
            </Html>
        );
    }
}

MyDocument.propTypes = propTypes;
MyDocument.defaultProps = defaultProps;

export default MyDocument;

Here’s an example of a page:

import React from 'react';
import PropTypes from 'prop-types';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { RichText } from 'prismic-reactjs';
import Page from '../layouts/main';
import { getPageData } from '../utils/page';
import IntroSection from '../components/about/section/Intro';
import MapSection from '../components/about/section/Map';
import FooterSection from '../components/landing/section/Footer';
import { RootView } from '../styles/page';

const propTypes = {
    title: PropTypes.array.isRequired,
    description: PropTypes.array.isRequired,
};

const AboutPage = ({ title, description }) => {
    title = JSON.parse(title);
    description = JSON.parse(description);

    const renderMainColumn = () => {
        return (
            <RootView>
                <IntroSection title={title} description={description} />
                <MapSection />
                <FooterSection />
            </RootView>
        );
    };

    return (
        <Page
            singleColumn
            fullWidth
            title={RichText.asText(title)}
            mainColumn={renderMainColumn()}
        />
    );
};

export async function getServerSideProps({ req, locale }) {
    const page = await getPageData(req, locale, 'about');

    return {
        props: {
            title: JSON.stringify(page.data.title),
            description: JSON.stringify(page.data.description),
            ...(await serverSideTranslations(locale, [
                'about',
                'common',
                'header',
                'footer',
            ])),
        },
    };
}

AboutPage.propTypes = propTypes;

export default AboutPage;

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 9
  • Comments: 18 (2 by maintainers)

Most upvoted comments

In my case following error Error: ReactDOMServer does not yet support Suspense. was caused by using useTranslation() with the wrong string (non existing i18n file) as an argument

So at the end of the day next-i18next

const { t } = useTranslation("fileThatDoesNotExist")

causes veeeeery vague error

It seems that adding the below settings to next-i18next-config.js is solving the problem:

react: {
  useSuspense: false,
  wait: true
}

I’m not using any kind of translation package… Is there any fix for a next.config.js?

I have the same bug with:

Passing in useSuspense: false even without passing wait: true solved this for me.