5.5 KiB
Context
ClawFort serves a static, client-rendered news experience backed by FastAPI endpoints and scheduled content refresh. The change introduces explicit technical requirements for crawlability, structured data quality, and delivery speed so SEO behavior is reliable across homepage, article cards, and static policy pages.
Current implementation already includes foundational metadata and partial performance behavior, but requirements are not yet codified in change specs. This design defines an implementation approach that keeps existing architecture (FastAPI + static frontend) while formalizing output guarantees required by search engines and validators.
Goals / Non-Goals
Goals:
- Define a deterministic metadata contract for homepage and static pages (description, canonical, robots, Open Graph, Twitter card fields).
- Define structured-data output for homepage (
Newspaper) and every rendered news item (NewsArticle) with stable required properties. - Define response-delivery expectations for compression and cache policy plus front-end media loading behavior.
- Keep requirements implementable in the current stack without introducing heavyweight infrastructure.
Non-Goals:
- Full SSR migration or framework replacement.
- Introduction of external CDN, edge workers, or managed caching tiers.
- Reworking editorial/news-fetch business logic.
- Rich-result optimization for types outside this scope (e.g., FAQ, VideoObject, LiveBlogPosting).
Decisions
Decision: Keep JSON-LD generation in the existing page runtime contract
Decision: Define structured data as JSON-LD embedded in index.html, populated from the same article data model used by hero/feed rendering.
Rationale:
- Avoids duplication between UI content and structured data.
- Preserves current architecture and deployment flow.
- Supports homepage-wide
@graphoutput containingNewspaperand multipleNewsArticlenodes.
Alternatives considered:
- Server-side rendered JSON-LD via template engine: rejected due to architectural drift and migration overhead.
- Microdata-only tagging: rejected because JSON-LD is simpler to maintain and validate for this use case.
Decision: Use standards-aligned required field baseline for NewsArticle
Decision: Require each NewsArticle node to include stable core fields: headline, description, image, datePublished, dateModified, url/mainEntityOfPage, inLanguage, publisher, and author.
Rationale:
- Produces predictable, testable output.
- Reduces schema validation regressions from partial payloads.
- Aligns with common crawler expectations for article entities.
Alternatives considered:
- Minimal schema with only headline/url: rejected due to weak semantic value and poorer validation confidence.
Decision: Enforce lightweight HTTP performance controls in-app
Decision: Treat transport optimization as explicit requirements using in-app compression middleware and response cache headers by route class (static assets, APIs, HTML pages).
Rationale:
- High impact with minimal infrastructure changes.
- Testable directly in integration checks.
- Works in current deployment topology.
Alternatives considered:
- Delegate entirely to reverse proxy/CDN: rejected because this repository currently controls delivery behavior directly.
Decision: Standardize lazy media loading behavior with shimmer placeholders
Decision: Define lazy-loading requirements for non-critical images and require shimmer placeholder states until image load/error resolution.
Rationale:
- Improves perceived performance and consistency.
- Helps reduce layout instability when paired with explicit image dimensions.
- Fits existing UI loading pattern.
Alternatives considered:
- Skeleton-only page-level placeholders: rejected because item-level shimmer provides better visual continuity.
Risks / Trade-offs
- [Risk] Dynamic metadata timing for client-rendered content -> Mitigation: require baseline static metadata defaults and deterministic runtime replacement after hero/article payload availability.
- [Risk] Overly aggressive cache behavior could stale fresh news -> Mitigation: short API max-age with stale-while-revalidate; separate longer static asset policy.
- [Trade-off] Strict validation vs. framework directives in markup -> Mitigation: define standards-compatible output goals and track exceptions where framework attributes are unavoidable.
- [Trade-off] More metadata fields increase maintenance -> Mitigation: centralize field mapping helpers and require parity with article model fields.
Migration Plan
- Implement and verify metadata/structured-data contracts on homepage and news-card rendering paths.
- Add/verify response compression and route-level cache directives in backend delivery layer.
- Align image loading UX requirements (lazy + shimmer + explicit dimensions) across hero/feed/modal contexts.
- Validate output with schema and HTML validation tooling, then fix conformance gaps.
- Document acceptance checks and rollback approach.
Rollback:
- Revert SEO/performance-specific frontend/backend changes to prior baseline while retaining unaffected feature behavior.
- Remove schema additions and route cache directives if they introduce regressions.
Open Questions
- Should policy pages (
/terms,/attribution) share a stricter noindex strategy or remain indexable by default? - Should canonical URLs include hash anchors for in-page article cards or stay route-level canonical only?
- Do we require locale-specific
og:locale/alternate tags in this phase or defer to a follow-up i18n SEO change?