Comments with Giscus, theme- and locale-synced
Wire up Giscus end-to-end — install the GitHub App, generate the IDs, set the env vars, sync theme + locale, and toggle comments per post.
Comments on this theme are powered by Giscus, which uses GitHub Discussions as the backend. No database, no moderation panel to log into — every comment is a discussion you can manage from the GitHub UI you already use.
If you scroll to the bottom of this post (and Giscus is configured), you will see the embed live. If it isn’t yet, you’ll see a friendly setup guide instead — the theme detects placeholder values and nudges you to fill them in.
Visit https://github.com/apps/giscus and grant the app access to the repository that will host your discussions. This is the repository where every comment will live as a Discussion.
Heads up: the repo must be public, and Discussions must be enabled in Settings → General → Features.
Open https://giscus.app and answer the prompts:
- Repository — the one you installed the app on.
- Page → Discussions Mapping — choose
pathname. This makes EN and FR translations of the same article get separate threads, which is what you want. - Discussion Category — pick or create one (e.g.
Announcements,Comments). Make sure it’s an announcement-style category so readers can’t open new top-level discussions on you. - The page generates four values:
repo,repoId,category,categoryId. Copy them.
Copy .env.example to .env and fill in the values:
PUBLIC_GISCUS_ENABLED=truePUBLIC_GISCUS_REPO=your-handle/your-repoPUBLIC_GISCUS_REPO_ID=R_xxxxxxxxxxxPUBLIC_GISCUS_CATEGORY=AnnouncementsPUBLIC_GISCUS_CATEGORY_ID=DIC_xxxxxxxxxxxRestart bun run dev. The setup notice should disappear and a real
embed should mount in its place.
You can also bypass .env entirely and edit
src/config.ts directly — GISCUS is a typed
object with all the same fields.
- Giscus is rendered only on post pages (not on listings, the home page, the about page, or 404).
- It is rendered only when
GISCUS.enabledistrueand the post does not opt out. - The iframe
data-langattribute is set from the current page’s locale — French posts get the French Giscus UI, English posts get the English UI. - The iframe theme follows the active daisyUI theme. When the
ThemeToggleflips, the Giscus island posts asetConfigmessage to the iframe so the comments instantly switch theme too.
Set comments: false in any post’s frontmatter to silence Giscus on
that single post:
---title: My quiet postcomments: false---This is useful for reference pages (like the frontmatter reference) where comments would only attract noise.
To explicitly enable comments on a post — in case you’ve toggled
them off elsewhere — set comments: true. If the field is omitted
entirely, the post inherits the site-wide setting.
Set PUBLIC_GISCUS_ENABLED=false (or remove it). Every post will then
show the simple “comments are disabled” line instead of the embed.
The Giscus client script is not loaded until the comments section
mounts. The relevant island is
src/components/islands/Giscus.astro.
It uses three states:
live→ comments are enabled, configured, and the iframe mounts.setup→ enabled but unconfigured (placeholder repo/IDs detected). Renders a friendly setup card instead of silence.disabled→ globally disabled or per-post opt-out. Renders a single italic line.
The placeholder detection looks for tell-tale strings like xxx or
your-handle/your-repo, so even forgetting to swap a value in .env
won’t lock readers out — they’ll see a friendly notice.
The full Giscus config is exposed in
src/config.ts:
export const GISCUS: GiscusConfig = { enabled: import.meta.env.PUBLIC_GISCUS_ENABLED === 'true', repo: import.meta.env.PUBLIC_GISCUS_REPO ?? 'your-handle/your-repo', // ... mapping: 'pathname', strict: '0', reactionsEnabled: '1', emitMetadata: '0', inputPosition: 'bottom', loading: 'lazy',};Tweak any of those fields freely — they map 1-to-1 to Giscus’s advanced usage options.