Skip to content

fix(seo): normalize meta descriptions to 160 chars and fix homepage head tag - #98

Merged
stysus merged 1 commit into
mainfrom
fix/seo-meta-description-duplication
Sep 20, 2026
Merged

stysus merged 1 commit into
mainfrom
fix/seo-meta-description-duplication

Conversation

@stysus

@stysus stysus commented Sep 20, 2026

Copy link
Copy Markdown
Member

Bug Description & Symptom

Bing Webmaster Tools reported "Too many pages with identical meta descriptions" across single article URLs and homepage. Crawlers were previously served duplicate global meta descriptions on non-existent slugs due to SPA fallback. Additionally, live article summaries contained raw newline breaks (\n\n) and exceeded 300-400 characters, while the homepage lacked an explicit <meta name="description"> tag in <svelte:head>.

Root Cause Analysis

  1. Early versions of the site defined a global static meta description in frontend/src/routes/+layout.svelte which was served on missing articles prior to 404 route handling.
  2. In the current engine, article.Summary was injected directly into HTML attributes without collapsing newlines or truncating to search engine character recommendations (150-160 chars).
  3. The homepage (+page.svelte) defined og:description and twitter:description but omitted <meta name="description">.

Proposed Fix

  1. Implemented cleanMetaDescription(text string, maxLen int) string in backend/internal/api/server.go:
    • Normalizes whitespace, collapsing newlines (\r\n), tabs, and multiple spaces into a single space.
    • Truncates cleanly at word boundaries within 160 characters, trimming trailing punctuation and appending ....
  2. Applied cleanMetaDescription in injectSEOTags and serveIndexHTML for article detail endpoints.
  3. Created frontend/src/lib/seo.ts with identical logic and applied it to <meta name="description">, og:description, twitter:description, and NewsArticle JSON-LD in frontend/src/routes/[slug]/+page.svelte.
  4. Added explicit <meta name="description"> in frontend/src/routes/+page.svelte and synchronized with canonical site metadata.
  5. Added unit test suite TestCleanMetaDescription in backend/internal/api/handlers_test.go.

Scope Lock & Blast Radius

  • Strict Scope Boundary: Fix is limited strictly to meta description normalization, SEO head synchronization, and test coverage.
  • No Symptom Patching: Addressed both server injection and client head generation cleanly at the root helper level.
  • Regression Test Added: TestCleanMetaDescription unit test covering edge cases, newlines, and truncation.

Mandatory Zero-Failure Pre-Commit Verification (AGENTS.md)

All commands below must be executed locally and pass with Exit Code 0 prior to creating the PR:

Backend Suite (if backend code changed)

  • gofmt -w . && gofmt -l . (Output must be completely empty)
  • go vet ./... (Static analysis clean)
  • go test -count=1 -v ./... (All tests pass with cache disabled)

Frontend Suite (if frontend code changed)

  • npm run format && npm run lint (Prettier code style & ESLint clean)
  • npm run check (SvelteKit TypeScript validation clean)
  • npm run build (Production build succeeds with static adapter)

Live Localhost End-to-End (E2E) Verification (Mandatory)

  • Server booted cleanly on localhost (go run ./cmd/server / preview) with 0 startup crashes/panics.
  • Live HTTP requests / UI workflows tested end-to-end against localhost matching implementation plan.
  • Server logs & responses verified clean with 0 unexpected HTTP errors (no unintended 4xx/5xx responses) and proper status codes (2xx/explicit error contracts).

Local Verification Evidence

=== Backend ===
gofmt -l: 0 unformatted files
go vet: clean
go test -count=1 ./...: PASS (all packages)
TestCleanMetaDescription: PASS

=== Frontend ===
npm run lint: All matched files use Prettier code style! 0 ESLint errors
npm run check: 0 errors
npm run build: Wrote site to "build" ✔ done

=== Live Localhost E2E ===
GET /: 200 OK (Clean title, meta description, og:description, twitter:description)
GET /microsoft-is-combining-its-copilot-apps-ahead-of-a-super-app-2: 200 OK (Clean 158-char single-line description with word boundary truncation)
GET /cuqa-on-hugging-face-democratizing-configurable-ai-agents: 404 Not Found (X-Robots-Tag: noindex, nofollow, 0 meta description tags)

…ead tag

- Add cleanMetaDescription in backend and frontend to normalize whitespace, collapse newlines, and truncate cleanly at 160-char word boundaries
- Add explicit meta description and sync OpenGraph tags on homepage (+page.svelte)
- Ensure single article detail and server injection output concise, single-line descriptions
- Add unit test suite TestCleanMetaDescription in api handlers
@stysus
stysus merged commit 85ec3a4 into main Sep 20, 2026
2 checks passed
@stysus
stysus deleted the fix/seo-meta-description-duplication branch September 20, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant