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.

Sergey Sypalo
  • 1,223
  • 5
  • 16
  • 35
  • 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. – juliomalves Oct 24 '22 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. – Sergey Sypalo Oct 25 '22 at 09:25

1 Answers1

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 */}}
        />}
    </>
}
juliomalves
  • 42,130
  • 20
  • 150
  • 146