How to add comments to a Blogger blog
Replace Blogger's built-in comments with EchoThread. Edit the theme XML, use expr: attributes to key threads to the post ID, and hide Blogger's own comment form.
On this page
Why Blogger + EchoThread
Blogger's comment system has barely changed in a decade. Replies nest exactly one level, there are no reactions, the spam filter is a black box you cannot tune, and the sign-in flow nudges every reader toward a Google account. For a blog with an actual audience, that is a discussion killed by friction.
EchoThread replaces it with threaded replies, emoji reactions, ML spam filtering, and sign-in with Google, GitHub, X, or Facebook — plus guest comments if you want them. The widget is under 60 KB gzipped and loads asynchronously from a CDN.
Prerequisites
- A Blogger blog you administer
- An EchoThread account — create one free
- Your site's API key from the EchoThread dashboard
Register your domain first. In the dashboard, add your site's domain to the EchoThread site. Comments will display without it, but EchoThread only hands a completed sign-in back to a domain you have registered — so skipping this looks like "reading works, signing in doesn't".
Step 1 — Back up your theme
In the Blogger dashboard go to Theme, open the arrow menu beside Customise, and choose Backup. This downloads the current theme XML. Do it before you change anything — a malformed theme will not save, and restoring the backup is the fastest way out.
Step 2 — Edit the theme XML
From the same arrow menu choose Edit HTML. Find the point in the Blog widget where the post body ends — searching for data:post.body gets you there — and add the EchoThread block after it:
<b:if cond='data:blog.pageType == "item"'>
<div id='echothread'
data-api-key='YOUR_API_KEY'
expr:data-page-url='data:post.url'
expr:data-identifier='data:post.id'
expr:data-page-title='data:post.title'/>
<script async='async' src='https://cdn.echothread.io/widget.js'></script>
</b:if>
Replace YOUR_API_KEY with the public API key from your EchoThread dashboard. It is designed to live in page source — it only lets visitors read and post on your registered site.
Three things about this snippet are Blogger-specific and none of them are optional:
- Single quotes. Blogger theme XML uses single-quoted attributes throughout. Double quotes inside a condition have to be escaped as
", which is why theb:ifabove looks the way it does. - The
expr:prefix. An attribute whose value comes from a data tag must be written asexpr:data-identifier='data:post.id'. Written without the prefix, Blogger outputs the literal textdata:post.id. - The
b:ifguard.data:blog.pageTypeisitemonly on a single-post page. Without the guard the widget would also load on the homepage and archive pages, once per post shown.
Click Save. Blogger validates the XML and refuses to save if it is malformed, so a successful save means the markup is at least well-formed.
Step 3 — Hide Blogger's comments
Blogger's own comment form is a separate widget, so adding EchoThread does not remove it. Go to Settings → Comments → Comment location and set it to Hide. Your existing comments are retained, just not displayed.
If you want those comments to carry over rather than disappear, export the blog from Settings → Manage blog → Back up content and use the importer in your EchoThread dashboard before hiding them.
Choosing an identifier
The snippet keys each thread to data:post.id, Blogger's numeric post ID. It never changes, so the discussion stays with the post even if you edit the title — which on Blogger rewrites the URL.
Using data:post.url as the identifier instead would work until the first title edit, and then silently start a new empty thread. Prefer the ID.
Troubleshooting
Blogger won't save the theme
The XML is malformed. The usual causes are a double quote that should be ", an unclosed tag, or a bare & in a URL. Blogger points at the offending line number — and if you are stuck, restore the backup from step 1 and start again.
The attributes render as literal text
You left off the expr: prefix. data-identifier='data:post.id' emits the string; expr:data-identifier='data:post.id' emits the ID.
Comments show on the homepage too
The b:if guard is missing or is checking the wrong value. It must be data:blog.pageType == "item".
Frequently asked questions
What's wrong with Blogger's built-in comments?
They work, but they are frozen in place: no threading beyond one reply level, no reactions, no spam filtering worth the name, and a sign-in flow that pushes readers toward a Google account. They also inherit whatever Google decides about the platform. EchoThread is a drop-in replacement that adds threading, emoji reactions, ML spam filtering, and four sign-in providers.
Do I need to edit the theme XML?
Yes. Blogger has no plugin system and no per-post code injection, so the theme is the only place to put post-level markup. The edit is one block, and Blogger keeps a backup of your theme that you can restore in one click if anything goes wrong.
Why do the attributes start with expr:?
Because a Blogger theme is XML, not HTML. A literal attribute is written normally, but an attribute whose value comes from a data tag has to be prefixed with expr: — so expr:data-identifier='data:post.id', not data-identifier='data:post.id'. Without the prefix Blogger emits the string data:post.id instead of the ID.
Will this slow down my blog?
No. The widget is under 60 KB gzipped, loads from a CDN, and is requested asynchronously, so it never blocks the page. It replaces the Blogger comment widget rather than loading alongside it.
Ready to add comments to your Blogger site?
Free for your first site. Set up in under 10 min.
Create free account