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.
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 */}}
/>}
</>
}