New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
example for react use #161
Comments
Nice, thanks! Also checkout https://github.com/b6pzeusbc54tvhw5jgpyw8pwz2x6gs/react-utterances |
neither do I, but I guess the important thing here is |
For a more concise approach to it, this is how I just did it on my repo:
This should be safe - you get the DOM elem, this gets invoked once on mount, and once with |
I love this, but I am wondering why it works now. It seems on subsequent renders, React would see that it is supposed to render an empty div and then delete the utterances iframe that was rendered in there by the script... |
I use GatsbyJs (react) I've run into some troubles installing utteranc.es. What I did wrong was I had included Here's the
I have my comments at
and my blog at live site is at : |
I wrote a guide here too https://www.vincentntang.com/installing-gatsbyjs-blog-comments/ |
Nice code, I used this but I had to check if the element already has child nodes, because this code creating a utterances child div every time i navigated to that page export const UtterancesComments: React.FC = () => (
<section
ref={(elem) => {
if (!elem || elem.childNodes.length) {
return;
}
...
}}
/>
); |
Using a hook: import { useEffect, useState } from 'react';
export const useUtterances = (commentNodeId) => {
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', ${YOUR_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);
};
}, [commentNodeId]);
}; Usage: import React from 'react';
import { useUtterances } from '../../hooks/useUtterances';
const commentNodeId = 'comments';
const Comments = () => {
useUtterances(commentNodeId);
return <div id={commentNodeId} />;
};
export default Comments; I've written an article which also shows how to lazy load, so that the comments show up when user reaches to the end of the page, (or wherever your comments are on the page), using Intersection Observer API. |
Typescript using @PsyGik's solutionimport 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])
} How do I react to theme change? @PsyGik you mention unmounting & remounting the component, how to do that? Isn't there a better way? |
@deadcoder0904 you can provide another argument to your import React from 'react'
// username/repo format
const REPO_NAME = '<username>/<repo>'
export const useUtterances = (commentNodeId: string, theme: 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', theme)
script.setAttribute('crossorigin', 'anonymous')
scriptParentNode.appendChild(script)
return () => {
// cleanup - remove the older script with previous theme
scriptParentNode.removeChild(scriptParentNode.firstChild as Node)
}
}, [commentNodeId, theme])
} Unfortunately because However, since us developers don't give up easy ;) , here's one using document.getElementsByClassName("utterances-frame")[0].contentWindow.postMessage({ type: "set-theme", theme: theme }, "*") Do note that there is a bit of an ugly color interchange thingy happening when the css is unloaded and new file is loaded |
@PsyGik Awesome. I tried both & I like the However, I'm getting a TS error on
My code is: DarkMode.tsxconst toggleTheme = () => {
const newTheme = resolvedTheme === 'light' ? 'dark' : 'light'
setTheme(newTheme)
// for utterances
const frame = document.getElementsByClassName('utterances-frame')[0] as HTMLIFrameElement
if (frame.contentWindow) {
const utterancesTheme = resolvedTheme === 'light' ? 'photon-dark' : 'github-light'
frame.contentWindow.postMessage({ type: 'set-theme', theme: utterancesTheme }, '*')
}
} useUtterances.tsimport React from 'react'
import { useTheme } from 'next-themes'
// username/repo format
const REPO_NAME = '<username>/<repo>'
export const useUtterances = (commentNodeId: string) => {
const { theme } = useTheme()
const utterancesTheme = theme === 'light' ? 'github-light' : 'photon-dark'
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', utterancesTheme)
script.setAttribute('crossorigin', 'anonymous')
scriptParentNode.appendChild(script)
return () => {
// cleanup - remove the older script with previous theme
scriptParentNode.removeChild(scriptParentNode.firstChild as Node)
}
}, [commentNodeId])
} I tried emptying the array as it says in the error but it re-renders the component. Same thing with adding Any ideas? This is a warning of ESlint. It works though so thank you :) |
Definitive solution here, without removeChild and appendChild, only with a replaceChildren, see the component in next:
enjoy :) |
hi @jdanyow,
Your work is awesome ! Just want to contribute this example made with JSX (react) cause it took me some time especially with the custom attributes for script tag.
Might be useful. And of course I'm gonna use your tool ! (I use gatsby js)
The text was updated successfully, but these errors were encountered: