Add Open Graph and Twitter Card meta-tags for link previews
Replace PathResourceResolver SPA fallback with SpaController that injects OG/Twitter meta-tags into cached index.html template. Event pages get event-specific tags (title, date, location), all other pages get generic fete branding. Includes og-image.png brand asset and forward-headers-strategy for proxy support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
83
specs/012-link-preview/plan.md
Normal file
83
specs/012-link-preview/plan.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Implementation Plan: Link Preview (Open Graph Meta-Tags)
|
||||
|
||||
**Branch**: `012-link-preview` | **Date**: 2026-03-09 | **Spec**: `specs/012-link-preview/spec.md`
|
||||
**Input**: Feature specification from `/specs/012-link-preview/spec.md`
|
||||
|
||||
## Summary
|
||||
|
||||
Inject Open Graph and Twitter Card meta-tags into the server-rendered HTML so that shared event links display rich preview cards in messengers and on social media. The Spring Boot backend replaces its current static SPA fallback with a controller that dynamically injects event-specific or generic meta-tags into the cached `index.html` template before serving it.
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: Java 25 (backend), TypeScript 5.9 (frontend — minimal changes)
|
||||
**Primary Dependencies**: Spring Boot 3.5.x (existing), Vue 3 (existing) — no new dependencies
|
||||
**Storage**: PostgreSQL via JPA (existing event data, read-only access)
|
||||
**Testing**: JUnit 5 + Spring MockMvc (backend), Playwright (E2E)
|
||||
**Target Platform**: Self-hosted Docker container (Linux)
|
||||
**Project Type**: Web application (SPA + REST API)
|
||||
**Performance Goals**: N/A — meta-tag injection adds negligible overhead (<1ms string replacement)
|
||||
**Constraints**: Meta-tags MUST be in initial HTML response (no client-side JS injection). No external services or CDNs.
|
||||
**Scale/Scope**: Affects all HTML page responses. No new database tables or API endpoints.
|
||||
|
||||
## Constitution Check
|
||||
|
||||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||||
|
||||
| Principle | Status | Notes |
|
||||
|---|---|---|
|
||||
| I. Privacy by Design | ✅ PASS | No tracking, analytics, or external services. Meta-tags contain only public event info (title, date, location). No PII exposed. `og:image` is a self-hosted static asset. |
|
||||
| II. Test-Driven Methodology | ✅ PLAN | Unit tests for meta-tag generation, integration tests for controller, E2E tests for full HTML verification. TDD enforced. |
|
||||
| III. API-First Development | ✅ N/A | No new API endpoints. This feature modifies HTML serving, not the REST API. Existing OpenAPI spec unchanged. |
|
||||
| IV. Simplicity & Quality | ✅ PASS | Simple string replacement in cached HTML template. No SSR framework, no prerendering service, no user-agent sniffing. Minimal moving parts. |
|
||||
| V. Dependency Discipline | ✅ PASS | Zero new dependencies. Uses only Spring Boot's existing capabilities. |
|
||||
| VI. Accessibility | ✅ N/A | Meta-tags are invisible to users. No UI changes. |
|
||||
|
||||
**Gate result: PASS** — No violations. No complexity tracking needed.
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```text
|
||||
specs/012-link-preview/
|
||||
├── plan.md # This file
|
||||
├── research.md # Phase 0 output — technical decisions
|
||||
├── data-model.md # Phase 1 output — meta-tag value objects
|
||||
├── quickstart.md # Phase 1 output — implementation guide
|
||||
├── contracts/
|
||||
│ └── html-meta-tags.md # Phase 1 output — meta-tag HTML contract
|
||||
└── tasks.md # Phase 2 output (created by /speckit.tasks)
|
||||
```
|
||||
|
||||
### Source Code (repository root)
|
||||
|
||||
```text
|
||||
backend/
|
||||
├── src/main/java/de/fete/
|
||||
│ ├── adapter/in/web/
|
||||
│ │ └── SpaController.java # NEW — serves index.html with injected meta-tags
|
||||
│ ├── application/
|
||||
│ │ └── OpenGraphService.java # NEW — composes meta-tag values from event data
|
||||
│ └── config/
|
||||
│ └── WebConfig.java # MODIFIED — remove PathResourceResolver SPA fallback
|
||||
├── src/main/resources/
|
||||
│ └── application.properties # MODIFIED — add forward-headers-strategy
|
||||
└── src/test/java/de/fete/
|
||||
├── adapter/in/web/
|
||||
│ └── SpaControllerTest.java # NEW — integration tests
|
||||
└── application/
|
||||
└── OpenGraphServiceTest.java # NEW — unit tests
|
||||
|
||||
frontend/
|
||||
├── index.html # MODIFIED — add <!-- OG_META_TAGS --> placeholder
|
||||
├── public/
|
||||
│ └── og-image.png # NEW — brand image for og:image (1200x630)
|
||||
└── e2e/
|
||||
└── link-preview.spec.ts # NEW — E2E tests
|
||||
```
|
||||
|
||||
**Structure Decision**: Web application structure (existing). Backend changes in adapter/web and application layers. Frontend changes minimal (HTML placeholder + static asset).
|
||||
|
||||
## Complexity Tracking
|
||||
|
||||
> No violations — section intentionally empty.
|
||||
Reference in New Issue
Block a user