1

I noticed in Vercel Analytics that when a page has Disqus comments embedded, it drastically decreases the page performance scores. So I want to have a button "Load comments" instead of actual comments and onClick load them.

I'm using the disqus-react npm package as a wrapper, but if there's going to be an implementation without it, it's also fine. I just tried to be as React-native as possible and use existing components instead of adding script blocks.

I found dynamic imports section https://nextjs.org/docs/advanced-features/dynamic-import as well as a few related articles onClick doesn't render new react component., NextJS dynamically add button onClick and What's the right way to do `onClick` in a NextJS component? but they are outdated or about other topics. Also, React 18.2 and NextJS 13.0 are released, so maybe there are new/better ways how to achieve my goal.

So far I have a following code:

import { DiscussionEmbed } from 'disqus-react'

export async function getStaticProps() {
    return {
        props: {
            ...posts.find(post => post.slug == 'my-best-post')
        }
    }
}

export default function Post(props) {
    return <>
        Post text....
        <DiscussionEmbed
            shortname='myid'
            config={        
                omitted for brevity
            }
        />
    </>
}

Dynamic exports official docs article has several options, with disabled SSR, with external library, shall I use both options? As technically I don't need comments to be generated on server.

2
  • Dynamically import DiscussionEmbed using next/dynamic and ssr: false, then only render it when the desired onClick event is triggered (use state variable to toggle it). This will only load the component's code when the click occurs. Commented Oct 24, 2022 at 18:17
  • Hey Julio, I came to more/less the same solution, but can't figure out how to import DiscussionEmbed, looking and the official docs example with fuse.js. Also, I'm not as good with React state. If you don't mind posting an answer with a code example I'll test and mark it as accepted. Commented Oct 25, 2022 at 9:25

1 Answer 1

0

In order to load the Disqus comments on-demand only, you can dynamically import DiscussionEmbed using next/dynamic with ssr: false. This prevents the component to be loaded during server-side rendering.

Next, you can use a state variable (let's say showComments) to toggle the rendering of the DiscussionEmbed when the button is clicked. Due to the dynamic import, this will only load the disqus-react code when the click occurs (you can check the devtools Network tab to see the additional requests that are made).

import { useState } from 'react'
import dynamic from 'next/dynamic'

// Dynamically import `DiscussionEmbed` on the client-side only
const DiscussionEmbed = dynamic(
    () => import('disqus-react').then((mod) => mod.DiscussionEmbed),
    { ssr: false }
)

export default function Post(props) {
    const [showComments, setShowComments] = useState(false)

    return <>
        <button onClick={() => setShowComments(true)}>Load Comments</button>
        {showComments && <DiscussionEmbed
            shortname="myid"
            config={{/* Your config here */}}
        />}
    </>
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot, also I had to add import {useState} from 'react' because got an error "ReferenceError: useState is not defined". So please add this line and I'll mark it as answered.
@SergeySypalo Yes, of course.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.