Load Utterances Comments only after someone scrolls to the bottom of the post #486
-
I want to add Utterances comments to my blog only after someone scrolls to the extreme bottom of the post. This excellent article adds a simple I would love to use it with For example, I have useUtterances.tsximport React from 'react'
// username/repo format
const REPO_NAME = '<username>/<repo>'
export const useUtterances = (commentNodeId: string) => {
React.useEffect(() => {
const scriptParentNode = document.getElementById(commentNodeId)
if (!scriptParentNode) return
// docs - https://utteranc.es/
const script = document.createElement('script')
script.src = 'https://utteranc.es/client.js'
script.async = true
script.setAttribute('repo', REPO_NAME)
script.setAttribute('issue-term', 'pathname')
script.setAttribute('label', 'comment :speech_balloon:')
script.setAttribute('theme', 'photon-dark')
script.setAttribute('crossorigin', 'anonymous')
scriptParentNode.appendChild(script)
return () => {
// cleanup - remove the older script with previous theme
scriptParentNode.removeChild(scriptParentNode.firstChild as Node)
}
}, [commentNodeId])
} This is my tutorial. tutorial/[slug].tsximport React from 'react'
import { GetStaticProps } from 'next'
import { getMDXComponent } from 'mdx-bundler/client'
import { useInView } from 'react-intersection-observer'
import { getAllTutorials, getTutorialBySlug } from '@/utils/index'
import { useUtterances } from '@/hooks/index'
import type { Post } from '@/types/index'
export const getStaticPaths = () => {
const tutorials = getAllTutorials()
const paths = tutorials.map(({ slug }) => ({
params: {
slug,
},
}))
return {
paths,
fallback: false,
}
}
export const getStaticProps: GetStaticProps<Post> = async ({ params }) => {
const slug = params?.slug as string
const tutorial = await getTutorialBySlug(slug)
return { props: tutorial }
}
const Tutorial = ({ meta, code }: Post) => {
const commentNodeId = 'comments'
const Component = React.useMemo(() => getMDXComponent(code), [code])
const { ref, inView, entry } = useInView({
/* Optional options */
threshold: 0,
})
useUtterances(commentNodeId)
return (
<>
<h2>Tutorial</h2>
<Component />
{inView ? <div id={commentNodeId} ref={ref} /> : null}
</>
)
}
export default Tutorial How do I load the The I did use the lazyImageLoad recipe but it isn't working. How do I load the script & the comment section only when user scrolls? Idk if it's best practice to load the script only when user scrolls so suggest me what's the better solution :) Edit: I also tried |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
Well, the {inView ? <div id={commentNodeId} ref={ref} /> : null} Would never do anything, since you only assign the useUtterances(inView ? commentNodeId : '') Make sure the element is triggered when you want it, maybe by making it |
Beta Was this translation helpful? Give feedback.
Well, the
useInView
will never trigger if it's not assigned to an element, so:Would never do anything, since you only assign the
ref
once it'sinView
(which would be never).In this case, the simplest approach is to simply not set the
commentNodeId
before the trigger element isinView
. Just make sureMake sure the element is triggered when you want it, maybe by making it
absolute
, so it can have a size without affecting the layout.You can look for the sentinel pattern, which is usually what's used when doing lazy loading. The "sentinel" being the trigger element.