Skip to main content

On This Page

Implement Lazy-Loaded, Privacy-First Comments in Astro with EchoThread

2 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

How to Add Comments to an Astro Site (Lazy-Loaded, Zero JS by Default)

EchoThread provides a privacy-first, threaded comment system that remains under 15 KB gzipped. By utilizing Astro’s component architecture, developers can ensure zero JavaScript is loaded until the reader scrolls to the widget.

Why This Matters

Traditional comment widgets often introduce significant performance bottlenecks and privacy concerns through heavy scripts and third-party tracking. In contrast, Astro’s architecture enables a ‘zero JS by default’ approach, allowing developers to maintain peak Core Web Vitals while still offering interactive features. Technically, this means the widget only loads its sub-15 KB script when the reader explicitly reaches the bottom of the content. This avoids unnecessary network requests and CPU cycles for visitors who only read the article, aligning technical execution with modern performance-first web standards.

Key Insights

  • EchoThread widget maintains a gzipped footprint under 15 KB for minimal performance impact (EchoThread, 2026).
  • Astro environment variables require the PUBLIC_ prefix to be accessible to the client-side widget.
  • IntersectionObserver implementation allows for true zero-JS until the reader enters a 200px margin of the comment section.
  • The widget automatically identifies unique threads using the page URL, simplifying management across static and SSR builds.
  • EchoThread is currently free during its beta phase and features a privacy-first, no-ads model.

Working Examples

Basic EchoThread Astro component structure.

---
const apiKey = import.meta.env.PUBLIC_ECHOTHREAD_API_KEY;
const { theme = "auto" } = Astro.props;
---
<section class="echothread-wrapper">
<div id="echothread" data-api-key={apiKey} data-theme={theme}></div>
<script src="https://cdn.echothread.io/widget.js" defer></script>
</section>

Lazy-loading the widget script using IntersectionObserver.

<script>
const section = document.getElementById("echothread-section");
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
const s = document.createElement("script");
s.src = "https://cdn.echothread.io/widget.js";
s.defer = true;
document.body.appendChild(s);
observer.disconnect();
}
}, { rootMargin: "200px" });
observer.observe(section);
</script>

Practical Applications

  • System: Astro Content Collections; Behavior: Use the EchoThread component in a BaseLayout to automatically generate unique comment threads per post URL.
  • Pitfall: Missing the PUBLIC_ prefix on the API key; Consequence: The client-side script cannot access the environment variable, leading to authentication errors.
  • System: Static sites requiring high SEO scores; Behavior: Implement IntersectionObserver to keep initial JavaScript execution at zero for non-scrolling users.

References:

Continue reading

Next article

How to Securely Connect AI Agents to Enterprise Tools via MCP Runtime

Related Content