> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase13-session03-seo-metadata-and-static-site-plumbing/spec.md).

# Session Specification

**Session ID**: `phase13-session03-seo-metadata-and-static-site-plumbing` **Phase**: 13 - Public Website Foundation **Status**: Complete **Created**: 2026-06-01 **Package**: public-website **Package Stack**: Astro 6.4.2 / TypeScript 5.9.3 static site

***

## 1. Session Overview

This session fills the metadata and static-site plumbing gap left intentionally in Session 02. The public website already has an Astro workspace, static output, sitemap integration, shared layouts, navigation, and a base visual shell. This session centralizes site identity data and connects canonical, social, robots, manifest, RSS, and structured metadata through reusable Astro components.

The work matters because later page and publishing sessions need one reliable metadata contract instead of route-local head markup. Crawlers, social previews, RSS readers, and accessibility tooling should receive consistent static output for `https://faction-os.com/` without adding runtime analytics, hosted forms, server-rendered routes, auth, CMS adapters, or other hosted-product claims.

The session is scoped to foundations only. Content collections and blog/news templates remain in Session 04. Approved brand/showcase asset promotion and the final Open Graph image fallback remain in Session 05, with this session using only existing reviewed static assets or an explicit temporary metadata fallback.

***

## 2. Objectives

1. Create a central site configuration module for canonical domain, external destinations, contact routes, and default metadata.
2. Implement reusable SEO and JSON-LD components for static Astro layouts.
3. Add static robots, manifest, favicon verification, and RSS route foundations.
4. Verify build, typecheck, lint, sitemap, RSS, robots, and metadata output without adding analytics or server runtime behavior.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase13-session01-astro-scaffold-and-workspace-wiring` - Provides the Astro workspace, package scripts, static output mode, MDX, sitemap, RSS dependency, and workspace wiring.
* [x] `phase13-session02-design-tokens-and-layout-shell` - Provides the shared layouts, shell, navigation, and BaseLayout metadata placeholder that this session replaces.

### Required Tools/Knowledge

* Astro static routes and document head composition.
* `@astrojs/rss` route handler basics.
* `@astrojs/sitemap` integration behavior.
* TypeScript strict object typing for shared metadata contracts.
* Project conventions for npm workspaces, Biome, ASCII-only files, and static public website boundaries.

### Environment Requirements

* Node.js 26.2.0 or newer and npm 11.16.0 per repository baseline.
* On this machine, prepend `/home/aiwithapex/.nvm/versions/node/v26.2.0/bin` to `PATH` before package commands if the default shell resolves Node 24.
* Run validation from the repository root or with `--prefix public-website`.

***

## 4. Scope

### In Scope (MVP)

* Search crawlers can resolve canonical URLs for static website pages - Add a normalized canonical helper and BaseLayout integration.
* Social crawlers can read Open Graph and Twitter metadata on starter pages - Add default metadata with safe per-page overrides.
* Site maintainers can update domain, demo URL, docs URL, contact destinations, and default descriptions in one place - Create `src/data/site.ts`.
* Crawlers can discover sitemap and crawl policy - Add `robots.txt` that references the sitemap and avoids non-existent private paths.
* Browsers can read install/display basics - Add `site.webmanifest` and link it from the SEO component.
* Feed consumers can discover a stable RSS endpoint - Add an RSS route scaffold that produces valid output and is ready for non-draft content in Session 04.
* Structured-data consumers can read conservative Organization, WebSite, and SoftwareApplication JSON-LD - Add a JSON-LD component using central site data.

### Out of Scope (Deferred)

* Final page-specific copy for every route - *Reason: page-building phases own final content and route expansion.*
* Blog/news content collections and templates - *Reason: Session 04 owns typed publishing surfaces and seed content.*
* Final Open Graph image asset pipeline - *Reason: Session 05 owns approved brand/showcase asset promotion and OG fallback selection.*
* Runtime analytics, trackers, or telemetry - *Reason: first-release boundary keeps analytics absent by default.*
* Hosted forms, auth, CMS adapters, server rendering, or Cloudflare adapter - *Reason: first release is a static Astro site.*

***

## 5. Technical Approach

### Architecture

The public website stays a static Astro workspace. `BaseLayout.astro` delegates all document metadata to `Seo.astro`, which reads central defaults from `src/data/site.ts` and accepts page-specific overrides from route and layout props. `Seo.astro` handles HTML metadata, canonical links, robots behavior, Open Graph, Twitter cards, RSS discovery, manifest links, and optional JSON-LD injection.

Static files under `public-website/public/` remain intentional pass-through assets only: `robots.txt`, `site.webmanifest`, and the existing favicon. The RSS route lives at `src/pages/rss.xml.js` so Astro emits a static feed during build. Until Session 04 adds collections, the feed returns a valid empty item list and documents the non-draft-only contract for later wiring.

### Design Patterns

* Central configuration: Keep domain, external destinations, contact targets, and default metadata in one typed module.
* Component-owned document head: Layouts pass metadata intent; `Seo.astro` owns tag generation and fallback behavior.
* Static route foundations: Prefer generated static files and Astro routes over runtime services.
* Claim boundaries: Metadata must not imply hosted identity, analytics capture, production-hosted validation, trusted erasure, or broad media readiness.

### Technology Stack

* Astro: 6.4.2
* `@astrojs/mdx`: 6.0.1
* `@astrojs/rss`: 4.0.18
* `@astrojs/sitemap`: 3.7.3
* TypeScript: 5.9.3
* Vite: 7.3.5
* Biome: root formatting and linting

***

## 6. Deliverables

### Files to Create

| File                                             | Purpose                                                                              | Est. Lines |
| ------------------------------------------------ | ------------------------------------------------------------------------------------ | ---------- |
| `public-website/src/data/site.ts`                | Central site identity, destinations, metadata defaults, and structured data seeds    | \~120      |
| `public-website/src/lib/metadata.ts`             | Canonical URL, robots, and metadata helper functions                                 | \~90       |
| `public-website/src/components/seo/Seo.astro`    | Reusable HTML metadata, social card, canonical, RSS, manifest, and JSON-LD component | \~120      |
| `public-website/src/components/seo/JsonLd.astro` | Safe structured-data script component                                                | \~40       |
| `public-website/src/pages/rss.xml.js`            | Static RSS feed scaffold ready for Session 04 content collections                    | \~45       |
| `public-website/public/robots.txt`               | Crawl policy and sitemap pointer                                                     | \~8        |
| `public-website/public/site.webmanifest`         | Static website manifest and icon metadata                                            | \~30       |

### Files to Modify

| File                                             | Changes                                                                           | Est. Lines |
| ------------------------------------------------ | --------------------------------------------------------------------------------- | ---------- |
| `public-website/src/layouts/BaseLayout.astro`    | Delegate head metadata to `Seo.astro` and expose metadata props                   | \~45       |
| `public-website/src/layouts/ContentLayout.astro` | Pass canonical and metadata overrides through shared content pages                | \~20       |
| `public-website/src/layouts/LegalLayout.astro`   | Preserve noindex behavior through the SEO component                               | \~15       |
| `public-website/src/pages/index.astro`           | Use explicit site metadata inputs for the starter homepage                        | \~15       |
| `public-website/public/favicon.svg`              | Verify or refine existing favicon metadata only if needed                         | \~5        |
| `public-website/astro.config.mjs`                | Verify site, static output, MDX, and sitemap posture; edit only if drift is found | \~5        |

***

## 7. Success Criteria

### Functional Requirements

* [ ] Built pages include canonical URLs rooted at `https://faction-os.com`.
* [ ] Starter pages include title, description, robots behavior, Open Graph, Twitter card metadata, RSS discovery, manifest link, and favicon link.
* [ ] Sitemap generation remains configured through `@astrojs/sitemap`.
* [ ] `robots.txt` allows normal crawl and references `https://faction-os.com/sitemap-index.xml`.
* [ ] `rss.xml` builds as a valid static feed and is ready to exclude drafts when Session 04 adds collections.
* [ ] JSON-LD output is conservative and does not make unsupported hosted, analytics, erasure, certification, or media-readiness claims.

### Testing Requirements

* [ ] Package typecheck passes.
* [ ] Package build passes.
* [ ] Focused Biome lint/format checks pass for touched website and session files.
* [ ] Generated `dist` metadata, sitemap, RSS, robots, and manifest artifacts are manually inspected.

### Non-Functional Requirements

* [ ] Static Astro output remains the deployment model.
* [ ] No analytics, trackers, hosted forms, auth, CMS adapter, React, Tailwind, shadcn/ui, or server adapter is added.
* [ ] Metadata uses absolute URLs where crawlers require them.
* [ ] External demo and docs links remain explicit and accessible.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.

***

## 8. Implementation Notes

### Key Considerations

* `public-website/src/layouts/BaseLayout.astro` already contains a Session 03 placeholder for Open Graph, Twitter, RSS, robots, and structured metadata.
* `astro.config.mjs` already sets `site: "https://faction-os.com"`, static output, MDX, and sitemap integration.
* `@astrojs/rss` is already present in `public-website/package.json`; no new package should be required for RSS.
* Use the existing `public/favicon.svg` as a temporary reviewed metadata asset only if an OG image path is required before Session 05 selects a better approved fallback.

### Potential Challenges

* RSS before content collections: Return a valid feed with no items and leave a clear integration point for Session 04.
* Open Graph image before asset promotion: Avoid promoting unknown-provenance brand/showcase media; use existing reviewed favicon metadata or document the temporary fallback.
* Duplicate metadata: Route and layout props should pass intent to `Seo.astro` rather than emitting head tags in multiple places.
* Node version drift: Use the Node 26.2.0 toolchain path if the shell default resolves an older Node version.

### Relevant Considerations

* \[P04] **Asset provenance gate remains active**: Do not promote unknown-provenance brand/showcase media. Keep OG fallback conservative until Session 05 reviews assets.
* \[P07] **Redaction is boundary-specific**: Site metadata and structured data should expose public labels and URLs only, never local paths, prompts, diagnostics, tokens, or raw payloads.
* \[P03] **Stable docs are the current contract**: Use stable README and docs references for public destinations instead of archived implementation detail.
* \[P07] **Hosted services ship as disabled-default guardrails only**: Do not add analytics, hosted persistence, public replay, or hosted identity claims.

### Behavioral Quality Focus

Checklist active: Yes Top behavioral risks for this session:

* Duplicate, contradictory, or missing metadata across layouts and routes.
* Invalid absolute URLs or canonical paths that break crawler output.
* Static metadata implying unsupported hosted, analytics, erasure, certification, or media-readiness claims.

***

## 9. Testing Strategy

### Unit Tests

* No package-local unit test harness is needed for this static metadata pass. TypeScript strict checks and focused linting cover helper contracts.

### Integration Tests

* Run `npm --prefix public-website run typecheck`.
* Run `npm --prefix public-website run build`.
* Inspect generated `dist/index.html`, `dist/rss.xml`, `dist/robots.txt`, `dist/site.webmanifest`, and sitemap output for expected static metadata.

### Manual Testing

* Open or inspect the generated homepage HTML and confirm canonical, title, description, Open Graph, Twitter, manifest, RSS, favicon, and JSON-LD tags.
* Confirm external demo and docs links remain accessible in the page output.

### Edge Cases

* Page passes `noindex`: SEO component emits deterministic robots content.
* Page passes relative canonical path: helper produces an absolute site URL.
* Page passes absolute canonical URL: helper preserves it.
* RSS has no content collections yet: feed still builds with an empty item list.
* Reduced metadata overrides: defaults fill missing title, description, and social values without route-level duplication.

***

## 10. Dependencies

### External Libraries

* `astro`: Existing static site framework.
* `@astrojs/rss`: Existing RSS route helper.
* `@astrojs/sitemap`: Existing sitemap integration.
* `@astrojs/mdx`: Existing MDX integration.

### Other Sessions

* **Depends on**: `phase13-session01-astro-scaffold-and-workspace-wiring`, `phase13-session02-design-tokens-and-layout-shell`
* **Depended by**: `phase13-session04-content-collections-and-publishing-templates`, `phase13-session05-asset-pipeline-and-brand-media-prep`, Phase 14 page implementation sessions

***

## Next Steps

Run the implement workflow step to begin AI-led implementation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase13-session03-seo-metadata-and-static-site-plumbing/spec.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
