GithubHelp home page GithubHelp logo

giscus / giscus Goto Github PK

View Code? Open in Web Editor NEW
7.2K 26.0 299.0 3.27 MB

A comment system powered by GitHub Discussions. :octocat: :speech_balloon: :gem:

Home Page: https://giscus.app

License: MIT License

JavaScript 3.19% TypeScript 83.76% CSS 13.05%
comments widget github-discussions giscus utterances github blog comments-widget comment-system hacktoberfest

giscus's Introduction

A comments system powered by GitHub Discussions. Let visitors leave comments and reactions on your website via GitHub! Heavily inspired by utterances.

Note giscus is still under active development. GitHub is also still actively developing Discussions and its API. Thus, some features of giscus may break or change over time.

How it works

When giscus loads, the GitHub Discussions search API is used to find the Discussion associated with the page based on a chosen mapping (URL, pathname, <title>, etc.). If a matching discussion cannot be found, the giscus bot will automatically create a discussion the first time someone leaves a comment or reaction.

To comment, visitors must authorize the giscus app to post on their behalf using the GitHub OAuth flow. Alternatively, visitors can comment on the GitHub Discussion directly. You can moderate the comments on GitHub.

If you're using giscus, consider starring 🌟 giscus on GitHub and adding the giscus topic to your repository! 🎉

Advanced usage

You can add additional configurations (e.g. allowing specific origins) by following the advanced usage guide.

To use giscus with React, Vue, or Svelte, check out the giscus component library.

Migrating

If you've previously used other systems that utilize GitHub Issues (e.g. utterances, gitalk), you can convert the existing issues into discussions. After the conversion, just make sure that the mapping between the discussion titles and the pages are correct, then giscus will automatically use the discussions.

Sites using giscus

Contributing

See CONTRIBUTING.md


This README is available in:

Powered by Vercel

giscus's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

giscus's Issues

Rename to giscus

How come did I not come up with this sooner???

It's shorter, it's also a play on Disqus, and, well... I don't know.

Should we do this??????????????

Is Tailwind the right choice?

When starting this project, I chose Tailwind for a few reasons:

  • I love it
  • I'm already familiar with it, so I don't need the extra time to learn other frameworks
  • I want to see how far I can get by creating my own styles (and a few other small libraries, e.g. github-syntax-light) to match GitHub's design.

However, when I started adding support for themes and other complex Markdown features (e.g. permalink code snippets), it started to become trickier to apply the correct style. It's not Tailwind's fault, it's just that the generated HTML is optimized for use with @primer's utilities, e.g. @primer/components, @primer/css, @primer/primitives.

Downsides to switching the frameworks/libraries used are:

  • I need more time to learn @primer stuff
  • I need time to rework the components
  • Increased bundle size.
    I tried just including @primer/css and it increased the build output by tens of kilobytes. Considering that the current size is only ~30KB and we managed to get it running quite beautifully, I really want to keep it small.

Support QnA-enabled category?

When creating a discussion category, there's an option to make it an "Open ended discussion" vs "Question / Answer". Discussions created in the latter category would have StackOverflow-style "selected answer" and other features enabled.

I don't know if this makes sense if we're embedding the discussion's comments on a webpage, though. I mean, we don't even include the discussion content itself, so...

Drop unused CSS variables

I'm just copying the variables from @primer/primitives and GitHub's website. There are a lot of unused variables in the current theme files. It would be nice if we could remove them at build time. I tried using PurgeCSS but I couldn't find the right configuration that plays well with the project's setup.

If the only option is to trim down the theme files, I'm also okay with it, as long as it's easy enough to re-add any variables that we need in the future.

Implement menu for KebabHorizontalIcon

Right now, the KebabHorizontalIcon is there just as a placeholder. We'll need to implement this, eventually.

GitHub:

image

I think we only need the "Copy link" and "Quote reply" menu items. For "Hide" and "Delete", I don't know if it's worth the effort. For "Edit", it would be awesome, but I imagine it wouldn't be so easy to implement. The thing is, if users really need to "Edit", "Hide", and "Delete" (or even "Report content"), they can always jump on GitHub 😆

Console warnings on load.

Hello,
This project is fantastic!

I have one gripe, and I'm happy to say it's a small one. I'm running giscus as a component in a Gatsby (React SSR) project. It seems to work perfectly, but there is a warning that comes up when a new post is loaded with giscus at the bottom:

[iFrameSizer][Host page: iFrameResizer0] [iFrame requested init] IFrame(iFrameResizer0) not found

This warning multiplies when new posts are loaded (e.g. the 1st post I click will have none, the 2nd will have one, the 3rd will have two and the 4th will have four).

I believe this means the following line in client.js is being run before the child exists, but I am unsure:

loadScript('https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.min.js', function () {
    return iFrameResize({ checkOrigin: [giscusOrigin], resizeFrom: 'child' });
});

Maybe it's my implementation? Here is the TSX component I've written for handling the script:

import React from "react"

type DataProps = {
  className?: string
}

const Comment: React.FC<DataProps> = ({ className }) => {
  // Used for https://giscus.app/
  // https://creativcoder.dev/how-to-add-github-utterances-blog
  const commentBox = React.createRef<HTMLInputElement>()

  React.useEffect(() => {
    const scriptEl = document.createElement("script")
    scriptEl.async = true
    scriptEl.src = "https://giscus.app/client.js"
    scriptEl.setAttribute("data-repo", "<STUFF>")
    scriptEl.setAttribute("data-repo-id", "<STUFF>")
    scriptEl.setAttribute("data-category", "Announcements")
    scriptEl.setAttribute("data-category-id", "<STUFF>")
    scriptEl.setAttribute("data-mapping", "title")
    scriptEl.setAttribute("data-reactions-enabled", "1")
    scriptEl.setAttribute("data-theme", "preferred_color_scheme")
    scriptEl.setAttribute("crossorigin", "anonymous")
    if (commentBox && commentBox.current) {
      while (commentBox.current.firstChild) 
		if (commentBox.current.lastChild) 
			commentBox.current.removeChild(commentBox.current.lastChild)
      commentBox.current.appendChild(scriptEl)
    }
  })

  return (<div ref={commentBox} className={`comments ${className}`} />)
}

export default Comment

Because these warnings don't affect functionally, this should be a low-priority issue.

Any help with this would be appreciated, thank you!

Progress tracker

This issue serves as a tracker for other issues that need to be resolved as we work towards 1.0 (do we even have versioning?). I'm currently listing these down so that I don't forget when I need to create separate issues later.

Meta

  • Landing page and onboarding steps (#43)
  • Client script (#44)
  • Logo (#45)
  • Contributing guide (#46)

Bugs/limitations

  • Cannot show more than 100 replies (#32)
  • Cannot toggle upvote (#31)

New features

  • Automatic discussion creation if no matching discussion exists (#33)
  • Other methods to find a matching discussion (e.g. discussionNumber, <title>, og:title, etc.) (#34)
  • Show/hide comment toggle for hidden comments and replies (#35)
  • KebabHorizontalIcon menu (add copy link and quote reply options) (#36)
  • New themes (#37)
  • Support Q&A mode (if that makes sense?) (#38)
  • Cover GFM edge cases/features (#47)

Improvements

  • Drop passthru GraphQL API when possible (#30)
  • Replace @peculiar/webcrypto with built-in Node crypto module (#29)
  • Improve error handling (#39)
  • Drop unused CSS variables (#48)
  • Audit security stuff (#40)
  • Audit accessibility stuff (#42)
  • Evaluate other data-fetching libraries (still in #32)
  • Evaluate @primer and other GitHub stuff (CSS libraries, components, etc.) (#41)

Handle rate limiting

Following #86.

GitHub's GraphQL API has a limit of 5000 query points/hour.

giscus authenticates as the app (bot) for the following operations:

  • Fetching repository information (repositoryId and categoryIds)
  • Fetching discussions anonymously (not signed in)
  • Posting new discussions (if no matching discussion exists)

For all other operations (posting comments, reactions, etc.) giscus authenticates as the user, so the 5000 points/hour limit is imposed on the user. In this case, I think the 5000 points/hour limit is generous. Going beyond that limit is highly unlikely, but possible (e.g. if the user also uses GitHub's API by other means).

The bot hitting the 5000 points/hour is more likely, especially if we have a lot of users (or maybe a few but with high traffic). At the very least, I think we should handle this case. A possible solution is to show an error message indicating the rate limit and a hint to sign in. Though at this point I think it wouldn't be much effort to also handle the case where the user already hits the rate limit.

For reference, utterances only sends a warning to the console when it hits the rate limit. It's also much easier to detect it on the REST API since you can just check the header. With the GraphQL API, you need to explicitly include rateLimit in the query.

Replace @peculiar/webcrypto with built-in Node crypto module

We use the webcrypto library to encrypt and decrypt user tokens. The encryption stuff is taken from this gist, while the flow is taken from utterances-oauth.

Node has built-in webcrypto as of version 15. However, it's not yet available on Vercel's serverless functions (which runs on AWS Lambda, I think?). They only use LTS releases of Node (currently Node 14). The latest LTS release, Node 16, was just released a few weeks ago. Looking at the time it took AWS to support Node 12 and 14, it's unlikely that Node 16 will land until at least a few months from now.

When Node 16 lands on Vercel, we can revert 3a52b18 to fix this issue.

However, I do believe that it's completely possible to achieve the same functionality using Node's crypto library (available on older Node versions), but I don't really know how. I'm no expert at cryptography, so I don't have enough confidence to pull this off.

Drop passthru GraphQL API

Right now, all GraphQL API calls for mutations are passed through /api/graphql before they are sent to GitHub. This is necessary because of community/community#3622. Once that is resolved, we can safely drop the passthru API.


Somewhat related, but for later:

Note that querying for discussions data will still need to be proxied through /api/discussions because GitHub's GraphQL API requires authentication for all requests. We're using a trick by authenticating as the app in order to get a token that can be used to fetch discussions data without signing in.

However, this means that GraphQL query string should be composed on the server. If we let the client compose the query and just use the passthru API (and supplying the token if the request doesn't have one), users can abuse this to run queries as the application.

We can remove /api/discussions once GitHub allows unauthenticated requests for their GraphQL API. (This is unlikely to happen in the near future, though.)

Add preferred color scheme option for theme

To make it easier for users who rely on preferred-color-scheme to configure their website's theme, we should add an option that supports it.

I think mapping the dark theme to dark and the light theme to light should be enough.

Cannot toggle upvote

I've already done this in #18 but for some reason GitHub throws FORBIDDEN errors. Maybe we need to ping some hubbers and see what's the issue?

More granular configuration of reactions

I'd love to be able to hide the text "XX reactions". Could we consider exposing that? I can't seem to do it via CSS due to iframe cross-domain.

Perhaps a way to take inline CSS? Should I develop a new theme instead?

Audit accessibility stuff

I'm no expert on accessibility, but this is one thing we definitely should do. I don't think I have added any aria attributes (sorry!) to the elements because I'd rather have a separate commit that deals with this. Help would be much appreciated!

Fix typo

Hello,

There is a small typo: Sign in to instead of Sign into

Screenshot 2021-06-03 at 19 55 47

Thanks!

Add other methods of finding the discussion

Currently, we search for discussions using the generic query string described in "Searching discussions."

On my personal website, I'm currently using the embedding page's pathname as the identifier for the discussion title.

Utterances supports:

  • Page pathname
  • Page URL
  • Page <title>
  • Page og:title meta tag
  • Specific term
  • Specific issue discussion number

For 1-5, I think we can still use the current logic. Most (if not all) of the work would only need to be done in the client installation script. This is because we should be able to just pass whatever the resulting string is to the search query string.

However, for 6, we'll need to access the discussion directly instead of using search. This is essentially the way we did it before 8d69b3c. Thus, we need to dynamically change the GraphQL query string based on the method that's used.

Create logo

This is hard... I want to do it myself but I don't know how it should look like 😬

Cannot show more than 100 replies to a single comment

We useSWRInfinite to implement cursor-based pagination. However, we need nested pagination in order to show more than 100 replies (the limit) to a comment. I haven't found an "easy" way to implement it with SWR. The key is to handle SWR key (heh) elegantly so that it can keep track of the pages correctly.

Thus, we might need to evaluate other data-fetching libraries such as react-query.

Or... we could fetch the remaining replies separately as a state for the Comment. Hmm...

Still... what kind of comment would get more than 100 replies anyway? 🤣

Link to the discussion

Please add a link to the discussion some where at the top so the user can visit the actual discussion itself.

image

Add event listener for when preferred_color_scheme changes.

Right now, on page load, preferred_color_scheme respects the system color scheme.

But, what if you're on a device that changes the system color scheme automatically? In those cases, giscus does not update and requires a page reload to continue respecting the system color scheme.

You could potentially solve this by using addEventListener to apply state changes like so:

const [mQuery, setMQuery] = React.useState<string>("light")

React.useEffect(() => {
  let mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")

  // Listening for changes.
  mediaQuery.addEventListener("change", e => {
    setMQuery(e.matches ? "dark" : "light")
  })

  // On initial load.
  setMQuery(mediaQuery.matches ? "dark" : "light")
}

FYI, that code snippet is untested.

Warning message in browser console

the console printed many warnings like this:

HTTP Referrer header: Length is over “4096” bytes limit - stripping referrer header down to origin: “https://giscus.app/”

browser: firefox

Instructions on self hosting

The README says the below:

Can be self-hosted! 🤳

Could you please provide instructions on how to do so? I myself am thinking of hosting it on cloudflare where my website already lives along with the same domain.

Also, can we self host the bot too? That would be helpful.

Jekyll plugin

This would be useful for standard Jekyll (Markdown) users (like me) who use Jekyll for blogging and want Giscus to follow Jekyll's blog post layout.

Multiple cascading search

Add the ability to have multiple search criteria like data-mapping="title|og:title". The page actually created automatically would be according to 1st criterial in the list.

In case one changes the criteria later, the conversations will not get unlinked from the page.

Cover GFM edge cases/features

GFM, in comments, has a lot of features, some of which we may not have covered. This issue serves as a placeholder for any edge cases/features that we need to cover in order to match GitHub's set of features.

Improve error handling

There's still a lot of places in the code where we can do error handling better. This is a placeholder issue for those improvements.

Add new themes

Themes are always nice! This is a placeholder issue for theme proposals.

I'll probably need to write a guide on how to do it, but you basically just need to create a new file in styles/themes following the other ones that already exist, then register it in here.

New themes should be able to provide a good contrast (at least in respect to the containing page's background). This tool might help: https://wave.webaim.org

Localization support

Hello!

I just discovered this commenting system and it seems to be nice. I tried till no utterances, but I am a little reluctant to try it on my blog as there is no localization option. Not so much work on this issue Will it be hard to add it to giscus?

Thank you and keep up the good work!

Report discussion metadata to the parent window.

Hello there,

This is an awesome project, thank you for making this.

I was wondering if there is any way to get the number of comments/replies/reactions or the discussion URL from the parent page.

I have two use cases for this:

  • Show the number of comments somewhere else on the same page.
  • Provide a link to the GitHub discussion, with a note saying that people can directly comment on GitHub - for the skeptics who don't want to provide access to the app.

I tried to query the dom, but the browser doesn't allow cross-origin iframes to be inspected from the parent window.

Are there any existing ways to achieve this?

If not, seeing that the iframe already sends messages to the parent window, would it possible to send some basic metadata about the discussion to the parent?

I took a quick look at the code and couldn't make much sense of it on the first go. But if you are unable to find time to make any changes, would you accept a PR? I could use any pointers if you have, on where to start.

Thanks & Regards
Sarath

Configurable comment sorting

Hi, I just saw this project and it looks great!

GitHub Discussions supports different sort orders for replies: newest/oldest/top first. This is configurable via buttons (on the right):

image

It would be great if these buttons would be also available on the embedded giscus form. Also, it would be cool if we could configure the default sort order for the comment form, e.g. via the javascript init function.

Right now it looks like giscus only supports oldest first ordering. Would it be possible to add custom orderings or is this not supported by GitHub's dicussion API?

Create contributing guide

To help new contributors, it would be nice if we have a contributing guide. It should at least cover:

  • How to get started with the project locally
  • Code structure (maybe use codetour?)
  • Dos and don'ts

Add a client API?

First off, thanks for this project, I love it!

I don't like a full refresh on each page change so I added barba.js in order to load the pages over AJAX instead. This obviously broke giscus, I hacked around a solution that involves changing the iframe src on page change via JS but I was wondering if there's a better way to solve this.

I don't know if that's possible but will you consider adding a JS client API so that we can programmatically load the discussion?

You can see my tiny js code here and you can see it in action at https://games-on-whales.github.io/gow/

Support anonymous comments

I think we can leverage getAppAccessToken() to post comments as the bot, allowing visitors to leave comments without signing in. Maybe we should also add a signature like

Anonymous wrote:

at the beginning of the posted comment, to indicate that it was made by an anonymous user (not the bot itself).

The thing is, we shouldn't pass the token directly to the client, because that would let users misuse the token to act as the bot. We need to create a new API route for addDiscussionComment and addDiscussionReply, and that's not something I'm really keen on.

Also, I'm not sure how/where the sign in buttons should be placed...

Edit:
Also mentioned below: anonymity and comments tend to not go well together. If implemented, this should be an opt-in feature.

Giscus fails when repository contains capitals

Discovered this when using Giscus with Jekyll as part of mmistakes/minimal-mistakes#3022

The PR takes the repository name from a setting, which in my case was SeanKilleen/seankilleen.github.io.

Giscus failed with a 400 error when retrieving comments, so thought there was no discussion topic, and therefore kept creating new discussion topics.

I think the issue is that the GitHub API or similar might be failing with a repo name that contains uppercase characters. I'll see if I can submit a PR to make that behavior case insensitive.

View Edit History

If a post is edited the ability to see the edit history when clicking the "edited" link

Get the number of comments outside of the blog page

I would like to get the number of comments made in a blog post. The goal is to show something like this:

the number of comments in the post

This is a good feature to have.
When looking at the comments counter, I just see a link to the discussion in the repo.

Create discussion automatically if no matching discussion exists

Right now, we need users to create the discussion before embedding it on a webpage.

Utterances allows automatic issue creation when the queried term doesn't exist. Discussion creation is a bit more complicated than issue creation.

To create an issue, we only need:

  • Repository owner
  • Repository name
  • Issue label name (if any)

On the other hand, to create a discussion, we need:

  • repositoryId (not owner/name)
  • categoryId (not category name)

We need to query for both of those before we can create a new discussion. We can retrieve them both in a single query, but still...

An alternative would be to fetch both of them in the onboarding process (on the homepage). Then, the generated installation script would be something like:

<script src="https://giscussions.vercel.app/client.js"
        repo="{repositoryId}"
        term="pathname"
        category="{categoryId}
        theme="dark_dimmed"
        crossorigin="anonymous"
        async>
</script>

Thus, the repositoryId and categoryId is baked into the widget. However, we cannot use repositoryId when searching for discussions; we need to use the owner/repo format. We can choose to include both repositoryId and owner/repo in the installation script, but that's a bit redundant 😬

Unrelated: If we used discussionNumber to fetch the discussion, we can use repositoryId because we'd access the discussion directly. However, that means the discussion is already created.

Anyway, then we would somehow pass that information to CommentBox, and try to create a new discussion if it fails to post a comment.

Audit security stuff

I'm no security expert. There certainly are things that can be changed to improve the security aspect of this project. They are things like:

  • The <iframe> tag and how the widget page behaves with it
  • Security headers (CORS, etc.)
  • Maybe store the session data (encrypted user token) in cookies instead of localStorage

The list is non-exhaustive, so this is just more like a placeholder issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.