Skip to content

feat: Embed Giscus for live voting and commenting in anchor modal #321

@raifdmueller

Description

@raifdmueller

Problem

Users must currently leave the website to vote or comment on an anchor (redirect to GitHub Discussions). The static feedback.json only updates daily via CI.

Proposed Solution

Embed Giscus as an iframe widget in the anchor modal. Giscus uses our existing GitHub Discussions as backend and handles OAuth transparently — users who are logged into GitHub can vote and comment without leaving the page.

Prerequisites

  • Install the Giscus GitHub App on LLM-Coding/Semantic-Anchors: https://github.com/apps/giscus
    • Select "Only select repositories" → Semantic-Anchors
    • This is required for Giscus to read/write discussions

Architecture

User clicks anchor card
    → Modal opens (existing)
    → Anchor content rendered (existing)
    → Static comments from feedback.json (existing)
    → Giscus iframe loaded (NEW)
        → Maps to existing Discussion via anchor-id
        → User can upvote, react, comment inline
        → GitHub OAuth handled by Giscus backend (Vercel-hosted)

How Giscus maps to our Discussions

Giscus supports mapping via data-mapping="specific" with data-term="⚓ arc42" — this matches the exact discussion title. Alternatively, we can use data-mapping="number" with the discussion number from feedback.json.

Since we already have feedback.json with the discussion URL (containing the number), we can extract the discussion number and use exact mapping. This avoids any ambiguity.

Implementation Plan

1. Giscus Configuration

<script src="https://giscus.app/client.js"
        data-repo="LLM-Coding/Semantic-Anchors"
        data-repo-id="R_kgDOQTHmRw"
        data-category="Anchor Feedback"
        data-category-id="DIC_kwDOQTHmR84C4oz7"
        data-mapping="number"
        data-term="{discussion-number}"
        data-reactions-enabled="1"
        data-emit-metadata="0"
        data-input-position="top"
        data-theme="preferred_color_scheme"
        data-lang="en"
        crossorigin="anonymous"
        async>
</script>

2. Modal Integration (anchor-modal.js)

  • After rendering the anchor content and static comments, inject a <div id="giscus-container">
  • Dynamically create and insert the Giscus <script> tag with the correct discussion number from feedback.json
  • When the modal is closed or a different anchor is opened, remove the Giscus iframe to reset state
  • Handle theme switching: Giscus supports postMessage to update theme dynamically

3. Theme Sync

Giscus can be themed via:

  • data-theme="preferred_color_scheme" (auto-detect) — simplest
  • data-theme="light" / data-theme="dark" — set based on our theme toggle
  • Runtime update via postMessage({ giscus: { setConfig: { theme: 'dark' } } })

We should sync with our existing dark/light toggle.

4. Language Sync

Set data-lang based on i18n.currentLang():

  • "en" or "de" — Giscus supports both

5. Discussion Number Extraction

From feedback.json, each anchor has a url like:

https://github.com/LLM-Coding/Semantic-Anchors/discussions/291

Extract the number: fb.url.split('/').pop()

6. Lazy Loading

Only load the Giscus script when the modal is opened, not on page load. This avoids unnecessary network requests and keeps the initial page load fast.

What changes vs. current implementation

Feature Current With Giscus
View comments Static from feedback.json (daily refresh) Live from GitHub
Add comment Redirect to GitHub Inline in modal
Upvote Redirect to GitHub Inline in modal
Reactions Not available Inline (8 emoji types)
Auth N/A One-time GitHub OAuth via Giscus

What stays

  • feedback.json with vote/comment counts for card grid badges (no auth needed for reading)
  • Daily CI refresh of feedback.json (for badge counts)
  • Vote/Discuss buttons as fallback links to GitHub

Considerations

  • Giscus backend: Hosted on Vercel by the Giscus maintainer. It proxies the OAuth token exchange. For full control, Giscus can be self-hosted.
  • Privacy: Giscus only communicates with GitHub's API. No tracking. The iframe loads from giscus.app.
  • CSP: GitHub Pages default CSP should allow the Giscus iframe. If not, may need to add frame-src giscus.app to the CSP headers.
  • Mobile: Giscus iframe is responsive and works on mobile.
  • Fallback: If Giscus fails to load, the static comments from feedback.json and the GitHub links still work.

Effort Estimate

  • Giscus App installation: 2 min (manual, one-time)
  • Modal integration: ~50 lines of JS
  • Theme/language sync: ~20 lines
  • CSS adjustments: ~10 lines
  • Testing: manual verification

Total: Small feature, mostly integration work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions