💡

Key Points

Key Takeaways

  • 1

    Transitioned from Giscus to Astro DB (native implementation) to enhance performance and data sovereignty.

  • 2

    Implemented robust international SEO (i18n) via automatically generated hreflang tags.

  • 3

    Improved discovery with separate language-specific RSS feeds and a 404 page with search functionality.

  • 4

    Fixed JS lifecycle bugs in View Transitions (SPA-like behavior).

Running a tech blog in 2025, “speed” is already a prerequisite . Thanks to frameworks like Astro, scoring perfect marks on Lighthouse is no longer difficult. The new battlegrounds are “Discovery,” “Engagement,” and “Sovereignty.”

This blog recently underwent a total architectural overhaul. This wasn”t just a visual refresh, “but a systematic “five-phase” engineering roadmap to meet modern SEO standards and user expectations.

This article is an accurate engineering log recording how we modernized the stack.

1

Phase 1: Foundation

Canonical, Partytown, Schema

2

Phase 2: Sovereignty

Astro DB, i18n

3

Phase 3: Discovery

Search 404, RSS

4

Phase 4: Experience

View Transitions

5

Phase 5: Content

AI Summary, Citations

Below is the conceptual diagram of the overhauled architecture. To protect the main thread, heavy processes (GA4) are offloaded to Worker, and dynamic data (comments) are fetched from a DB close to the edge.

Phase 1: The Technical Foundation

Before adding new features, we needed to eliminate the “invisible debt” that was harming rankings.

1. Canonical Standardization

Search engines dislike ambiguity. If both /blog/post/ and /blog/post exist, evaluation is scattered. Therefore, “we applied a strict “No Trailing Slash” policy.

Changes:

  1. Astro Config : Explicitly set trailingSlash: "never".
  2. Canonical Logic : Updated the BaseHead component to remove the trailing slash from generated URLs.
astro.config.mjs
export default defineConfig({
 // ...
 trailingSlash: "never",
 build: {
 format: "file",
 },
});

2. Zero-Blocking Analytics with Partytown

Google Analytics 4 (GA4) is heavy. Loading this on the main thread is a “sin” in terms of performance. As a countermeasure, we introduced Partytown to offload GA4 to a Web Worker.

ℹ️
The Result

The main thread is liberated for UI interactions, and analysis scripts now run quietly in a background thread.

3. Advanced Structured Data (JSON-LD)

To rank high in “How-to” queries, excellent text alone is not enough. You need structured data. We expanded the JsonLd.astro component to dynamically output FAQPage or HowTo schemas depending on the content type.

Phase 2: Engagement & Sovereignty

For years, developer blogs have relied on “leased” comment systems like Disqus or Giscus. We decided to reclaim sovereignty over this data.

Native Comment Feature with Astro DB

We migrated from Giscus, which uses the GitHub Discussions API, to a native Astro DB (LibSQL) solution.

Why?

  • Performance : Third-party iframe loading drops to zero.
  • Control : The data is ours. No more forcing GitHub accounts on commenters (e.g., “if we want to allow guest posts in the future).
  • UI : Seamless integration with the design system instead of a patched-on widget.

Below is a great video explaining the Astro DB concept.

引用: Tomosta | Makoto Taniguchi

International SEO (i18n)

Since this blog serves readers in Japan, the US, and China, standard SEO isn’t enough. Therefore, we implemented automated hreflang generation.

src/components/seo/BaseHead.astro
{slug && (
 <>
 <link rel="alternate " hreflang="ja" href={new URL(`/blog/${slug}`, site).href} />
 <link rel="alternate " hreflang="en" href={new URL(`/en/blog/${slug}`, site).href} />
 <link rel="alternate " hreflang="zh" href={new URL(`/zh/blog/${slug}`, site).href} />
 <link rel="alternate " hreflang="x-default" href={new URL(`/blog/${slug}`, site).href} />
 </>
)}

This allows Google to appropriately provide the English version to US users and the Japanese version to users in Tokyo.

Phase 3: Discovery Engineering

A 404 page should not be a dead end; it should be a “turning point.”

Search-First 404 Page

We enhanced the 404 layout and placed a prominent Search Dialog . Instead of having lost users bounce, it guides them by asking, “What were you looking for?”

Splitting RSS Feeds

The previous RSS feed was a “dump” where languages were mixed. This is noise for users. Therefore, “we split the logic as follows:

  • /rss.xml: Japanese (Default)
  • /en/rss.xml: English only
  • /zh/rss.xml: Chinese only
Project Structure
📂
public /
📄
rss.xml
📂
en /
📄
rss.xml
📂
zh /
📄
rss.xml

This allows us to respect users” subscription settings and reduce unsubscribes.

Phase 4: SPA Experience (View Transitions)

Astro’s View Transitions make static sites feel like native apps. However, they also bring complexity. Scripts that rely on window.onload or DOMContentLoaded only run once and break after page transitions.

引用: Beyond Fireship

Behind the Scenes: The Battle of the Copy Button

The “Copy Code” button worked after a hard refresh, “but died after navigating via a link. The fix was to move lifecycle events to astro:page-load.

CopyCodeButton.astro
// Before (breaks on page transition)
// document.addEventListener("DOMContentLoaded", () => { ... });

// After (View Transitions compatible)
document.addEventListener("astro:page-load", () => {
 const codeBlocks = document.querySelectorAll("pre");
 // ... hydration logic
});

Phase 5: Content Engineering

Finally, we decided to treat content Frontmatter as a database.

AI Summary Field

We added an ai_summary array field to the content schema.

// src/content/config.ts
ai_summary: z.array(z.string()).optional(),

When this field is filled (by us or an AI agent), the AISummary component automatically renders a summary at the beginning of the article. This respects readers” time and improves scannability.

Conclusion

Modernizing a blog is not just about rewriting CSS. It”s about respecting the “user”s state (language, subscriptions)” and the “machine”s requirements (schema, speed).”

Check out our other engineering logs to see how this platform continues to evolve.