Add comments to an Astro site
Astro ships zero JavaScript by default, which is exactly why it pairs well with a comment widget that weighs a few kilobytes and loads lazily. Connect integrates as a small component.
1. Create the component
Create src/components/Comments.astro:
---
interface Props {
pageId?: string
}
const { pageId } = Astro.props
---
<div id="hakanai-connect"></div>
<script
is:inline
async
src="https://connect.hakanai.io/embed.js"
data-key="YOUR_SITE_KEY"
data-page-id={pageId ?? Astro.url.pathname}
></script>
Replace YOUR_SITE_KEY with the public key from your dashboard.
Two Astro-specific details matter here:
is:inlineis required. Without it, Astro processes the script, strips thedata-*attributes, and bundles the source, which breaks the widget.is:inlinetells Astro to render the tag exactly as written.- The component accepts an optional
pageIdprop and falls back to the pathname. Passing the post slug gives you a page identity that survives URL changes.
2. Use it in your blog layout
In your post layout, for example src/layouts/BlogPost.astro:
---
import Comments from '../components/Comments.astro'
const { slug } = Astro.props
---
<article>
<slot />
</article>
<Comments pageId={slug} />
With content collections, slug typically comes from Astro.props or the collection entry. Any stable string works.
View Transitions
If your site uses <ClientRouter /> (formerly <ViewTransitions />), Astro swaps page content without a full reload, and inline scripts do not re-execute by default. Add data-astro-rerun to the script tag in the component:
<script
is:inline
async
data-astro-rerun
src="https://connect.hakanai.io/embed.js"
...
></script>
The widget guards against double initialization, so re-running the script on a page that already has a thread is safe.
Comment counts on list pages
On your blog index, add a counter element per post:
<span data-connect-count={post.slug}></span>
Then follow the comment counts guide. Use the same values as your page ids so counts and threads match.
Local preview
astro dev runs on localhost, which is not one of your declared domains, so comment submission is rejected there. Reading works. Add your staging domain under Site settings if you want to test posting before going live.