Files
astro-website/openspec/changes/blogs-section/design.md
Santhosh Janardhanan c773affbc8
Some checks failed
ci / site (push) Has been cancelled
Wordpress is in
2026-02-10 01:04:12 -05:00

3.3 KiB
Raw Blame History

Context

The site is currently a static Astro build served via nginx. Content is populated by a build-time fetch step (site/scripts/fetch-content.ts) that writes a repo-local cache file consumed by the Astro pages/components.

We want to add a new Blog section backed by a WordPress site via the wp-json REST APIs, including:

  • a primary header nav link (/blog)
  • blog listing pages (cards with featured image, title, excerpt)
  • blog detail pages (full content)
  • a blog-only secondary navigation based on WordPress categories
  • support for both WordPress posts and pages

Goals / Non-Goals

Goals:

  • Add /blog with a listing of WordPress posts rendered as static HTML at build time.
  • Add detail pages for WordPress posts and pages, rendered as static HTML at build time.
  • Add category-based browsing within the Blog section (secondary navigation + category listing pages).
  • Use environment variables for WordPress configuration (site URL and credentials) and fetch via wp-json.
  • Keep pages indexable and included in sitemap output.

Non-Goals:

  • Real-time updates without rebuilds (v1 remains build-time fetched).
  • Implementing “like” storage in WordPress or a database (nice-to-have can be a simple outbound share action later).
  • Full WordPress theme parity (we render a simplified reading surface).

Decisions

  • Decision: Build-time ingestion into the existing content cache.

    • Rationale: Matches the current architecture (cache file + static build), keeps the site fast and crawlable, and avoids introducing a runtime server layer.
    • Alternative: Client-side fetch from WP directly. Rejected for SEO and performance (would rely on client rendering and adds CORS/auth complexity).
  • Decision: Prefer WordPress Application Passwords over raw user passwords (if possible).

    • Rationale: Application passwords are the standard WP approach for API access and can be revoked without changing the user login password.
    • Alternative: Basic auth with username/password. Allowed if thats what your WP setup supports, but we should treat credentials as secrets in .env.
  • Decision: Normalize WordPress content into a small internal schema.

    • Rationale: Keeps UI components simple and consistent with existing content rendering patterns (cards + detail pages).
    • Implementation: Add a wordpress source to the cache schema, with fields for id, slug, kind (post|page), title, excerpt, contentHtml, featuredImageUrl, publishedAt, updatedAt, categories.
  • Decision: Route structure.

    • Rationale: Keep URLs clear and stable.
    • Proposed:
      • /blog (latest posts)
      • /blog/category/<slug> (posts in category)
      • /blog/post/<slug> (post detail)
      • /blog/page/<slug> (page detail)

Risks / Trade-offs

  • [Risk] WP API rate limits / downtime break the build. → Mitigation: Cache last-known-good content.json; on fetch failure, retain existing cache and log errors.
  • [Risk] WordPress HTML content can contain unexpected markup or scripts. → Mitigation: Render server-side as HTML but sanitize or strip scripts; document allowed HTML subset.
  • [Risk] Auth method differs per WP hosting. → Mitigation: Support both public endpoints for reading (preferred) and authenticated requests when needed; keep config flexible.