GitHub - gitalk/gitalk: Gitalk — a comment component based on GitHub Discussions (current, 2.x). The GitHub Issues based 1.x line is end-of-life. · GitHub
Skip to content
gitalkPublic

About

Gitalk — a comment component based on GitHub Discussions (current, 2.x). The GitHub Issues based 1.x line is end-of-life.

Topics

Resources

Stars

7.2k stars

Watchers

47 watching

Forks

Repository files navigation

Gitalk 2.0

A comment component backed by GitHub Discussions (default) or GitHub Issues. No backend, no database, no third-party proxy.

中文文档 · Demo · Discussions

Quick start

Three steps. Step 1 is the only one that needs a browser and a repository you administer; the rest is copy-paste.

1. Put the App on a repository

Gitalk 2.0 uses a GitHub App, not the 1.x OAuth App: it lets the token endpoint mint an installation token without shipping a secret to the browser.

The complete setup — public repository, Discussions, App permissions, installing the App on that repository, credentials and the callback URL — is documented once, in the deploy CLI's README. Creating the App is not enough: without the installation the proxy has no token, and anonymous reads fall back to 60 requests/hour.

The App's client secret never goes in your page. It lives in the token endpoint; see The token endpoint.

2. Install the packages

pnpm add @aifire/gitalk          # framework-free
pnpm add @aifire/gitalk-react    # React
pnpm add @aifire/gitalk-vue      # Vue

Or skip the build step entirely:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@aifire/gitalk@latest/dist/gitalk.css">
<script src="https://cdn.jsdelivr.net/npm/@aifire/gitalk@latest/dist/gitalk.js"></script>

Until the first release is published, these are not on the registry yet — build from source as described in Development.

3. Render it

No framework

<div id="gitalk-container"></div>
<script>
  const gitalk = new Gitalk({
    clientID: 'Iv1.xxxxxxxxxxxx',   // example value: your App's Client ID
    owner: 'octocat',               // repository that stores the comments
    repo: 'demo-repo',              // name only, never `octocat/demo-repo`
    admin: ['octocat'],             // who may create the thread on first visit
    number: 42,                     // the discussion number for this page
    proxy: 'https://my-niubi-gitalk.octocat.workers.dev' // the origin the deploy printed
  })
  gitalk.render('gitalk-container')
</script>

React

import { Gitalk } from '@aifire/gitalk-react'
import '@aifire/gitalk/style.css'

export function Comments() {
  return (
    <Gitalk
      options={{
        clientID: 'Iv1.xxxxxxxxxxxx',
        owner: 'octocat',
        repo: 'demo-repo',
        admin: ['octocat'],
        number: 42,
        proxy: 'https://my-niubi-gitalk.octocat.workers.dev'
      }}
    />
  )
}

Vue

<script setup lang="ts">
import { Gitalk } from '@aifire/gitalk-vue'
import '@aifire/gitalk/style.css'

const options = {
  clientID: 'Iv1.xxxxxxxxxxxx',
  owner: 'octocat',
  repo: 'demo-repo',
  admin: ['octocat'],
  number: 42,
  proxy: 'https://my-niubi-gitalk.octocat.workers.dev'
}
</script>

<template>
  <Gitalk :options="options" />
</template>

Options

Option Default Notes
clientID — Your GitHub App's client id
owner, repo — Repository hosting the discussions
admin [] Users who may create the thread
backend 'discussions' or 'issues' for existing 1.x installs
number — Discussion number. Recommended: avoids a title scan
id location.pathname Page identifier used when no number is given
category — Discussions category slug/name used when creating
perPage 10 Page size
proxy project's own endpoint Your proxy's origin. Required in practice: see The token endpoint
language navigator.language 11 locales carried over from 1.x

The token endpoint

github.com/login/oauth/access_token sends no Access-Control-Allow-Origin header, and the device flow is CORS-blocked too, so a static page cannot complete the OAuth exchange by itself. Something server-side has to hold the client secret.

Gitalk's built-in default is the endpoint this project runs, and it only serves this project's own sites: its origin allowlist is not open to third parties, so another domain is rejected by CORS before GitHub is ever contacted. Deploy your own — one command, free tier, about a minute:

npx github:gitalk/deploy -c .env -t cloudflare

CloudBase is supported too (-t cloudbase, needs a CloudBase environment and Tencent Cloud keys), as is self-hosting on Node. The complete setup — repository preparation, App permissions, installing the App on your repository, credentials, .env, the callback URL — is documented once, in the deploy CLI's README. Only that file lists the steps; this README does not repeat them.

Then pass the origin it printed:

{ proxy: 'https://my-niubi-gitalk.octocat.workers.dev' }

The endpoint only ever sees an OAuth code or an encrypted session — never your client secret from the browser, and never a visitor's raw token in a URL.

Rate limits

Visitor Path Limit
Logged out, proxy set and App installed Canonical GraphQL reads through your proxy, with the installation token 5,000 per hour
Logged out, no proxy or App not installed GitHub REST, straight from the browser 60 requests/hour per IP
Logged in GitHub REST / GraphQL, with the visitor's own token 5,000 per hour

When proxy is set, anonymous reads take the proxy's canonical GraphQL path and spend the installation token's 5,000/hour; if that path cannot answer (proxy unreachable, App not installed, private repository), the widget falls back to the CORS-enabled REST read straight from the browser, which needs no credential and counts against the anonymous per-IP budget. Writing must use GraphQL (GitHub exposes no REST write API for discussions), which is why posting requires signing in. See docs/tech.md §2.1 for the measured matrix.

Sessions last 30 days and renew silently when the App is configured to expire access tokens; see docs/tech.md §3.7.

Migrating from 1.x

Your old comments live in Issues, so they will not appear in Discussions. Pass backend: 'issues' to keep reading and writing them:

{ backend: 'issues' }

The clientID still changes: 1.x used an OAuth App, 2.0 needs a GitHub App.

What changed from 1.x

1.x 2.0
Storage GitHub Issues GitHub Discussions (Issues optional)
Toolchain webpack 3 · Babel 6 · Preact 8 Vite 8 · TypeScript 7 · Preact 11
Auth clientSecret in the page + third-party CORS proxy your own edge function, no secret in the browser
Versioning standard-version release-please
Builds UMD only ESM + IIFE + React + Vue

Full rationale, including every measured API behaviour, is in docs/tech.md.

Development

pnpm install
pnpm dev            # landing page with a live widget
pnpm test           # 68 tests
pnpm build          # all packages
pnpm typecheck

Releases are cut by release-please: merge the Release PR it opens and CI publishes to npm via OIDC. See .github/workflows/publish.yml.

License

MIT

About

Gitalk — a comment component based on GitHub Discussions (current, 2.x). The GitHub Issues based 1.x line is end-of-life.

Topics

Resources

Stars

7.2k stars

Watchers

47 watching

Forks

Releases

Packages

Used by

Contributors

Languages