Skip to content

feat(seo): structured data + social metadata (+ favicon & download dropdown fixes) - #81

Merged
wavekat-eason merged 3 commits into
mainfrom
feat/seo-structured-data
Jun 4, 2026
Merged

feat(seo): structured data + social metadata (+ favicon & download dropdown fixes)#81
wavekat-eason merged 3 commits into
mainfrom
feat/seo-structured-data

Conversation

@wavekat-eason

@wavekat-eason wavekat-eason commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Started as an SEO review and grew two small related fixes. The SEO baseline was already solid (canonical URLs, OG/Twitter cards, per-page titles & descriptions, sitemap, RSS, Article JSON-LD on posts); this closes the remaining gaps for ranking and rich-result eligibility, then fixes a 404ing favicon and a download-dropdown UX bug found along the way.

SEO

Sitewide — src/layouts/Base.astro

  • Organization + WebSite JSON-LD (@graph) with logo and sameAs → GitHub org + LinkedIn. Gives search engines a single WaveKat entity; other schemas reference it via @id.
  • Completed social metadata: og:site_name, og:locale, og:image:alt, twitter:image:alt.
  • robots directive (+ a noindex prop for opting pages out) and light/dark theme-color.
  • New ogType / article props so child layouts can emit proper article semantics.

Blog posts — src/layouts/Post.astro

  • Emits og:type=article + article:published_time / modified_time / author / tag.
  • Upgraded JSON-LD from generic ArticleBlogPosting (mainEntityOfPage, url, image, keywords, publisher logo, guaranteed dateModified).

Voice product page — src/pages/voice/index.astro

  • SoftwareApplication schema (category, operatingSystem: macOS, Linux, live version, free $0 Offer).
  • FAQPage schema generated from the existing on-page FAQ.

Fixes

Dark-mode favicon 404 — scripts/sync-brand.js

Base.astro references wavekat-icon-dark.svg as the dark-mode favicon, but the brand sync only copied the light variant, so dark-mode visitors got a 404. Added it to the sync list (the asset already exists in wavekat-brand).

Download dropdown didn't close on outside click — src/components/VoiceDownload.astro

The "other platforms" control is a native <details>, which only toggles via its <summary> — clicking elsewhere left it open. Added a small inline script to close any open dropdown on an outside click or Escape, matching expected menu behaviour. Still works with JS off via the native <details>.

Testing

  • astro build passes; all structured-data and meta tags verified in the rendered HTML across homepage, voice, and blog pages.
  • npm run sync confirmed to copy both light and dark icon variants into public/logos/.

🤖 Generated with Claude Code

Eason and others added 2 commits June 4, 2026 21:02
Add sitewide Organization/WebSite JSON-LD (logo + sameAs to GitHub and
LinkedIn), and complete the social-card metadata: og:site_name, og:locale,
og:image:alt, twitter:image:alt, theme-color, and a robots directive.

Blog posts now emit og:type=article with article:* meta and upgrade their
JSON-LD to BlogPosting (mainEntityOfPage, image, keywords, publisher logo).

The Voice product page gains SoftwareApplication (free Offer, macOS/Linux,
live version) and FAQPage structured data for rich-result eligibility.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Base.astro references wavekat-icon-dark.svg as the dark-mode favicon, but
the brand sync only copied the light variant, so dark-mode visitors got a
404. Add it to the sync list (the asset already exists in wavekat-brand).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

The 'other platforms' control is a native <details>, which only toggles via
its <summary> — clicking elsewhere left it open. Close any open dropdown on
an outside click or Escape, matching expected menu behaviour. Still works
with JS off via the native <details>.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@wavekat-eason wavekat-eason changed the title feat(seo): structured data + richer social metadata feat(seo): structured data + social metadata (+ favicon & download dropdown fixes) Jun 4, 2026
@wavekat-eason
wavekat-eason merged commit d8fb369 into main Jun 4, 2026
2 checks passed
@wavekat-eason
wavekat-eason deleted the feat/seo-structured-data branch June 4, 2026 09:20
wavekat-eason added a commit that referenced this pull request Jun 4, 2026
## Summary

Adds a data-driven **alternatives module** under the Voice section —
multiple pages, not one, so each comparison can rank for its own "<name>
alternative" search intent.

- **`src/lib/voice-alternatives.ts`** — single source of truth. One
entry per competitor (SEO title/description, honest "what it is", a
capability comparison table, choose-them/choose-us lists, FAQs). Adding
a competitor = append one entry.
- **`/voice/alternatives/`** — hub page; emits `ItemList` schema, links
out, ranks for the broad term.
- **`/voice/alternatives/[slug]/`** — one page per competitor via
`getStaticPaths`; emits `FAQPage` + `BreadcrumbList` schema.
- **`Voice.astro`** — adds the `alternatives` sub-nav tab and a
prefix-based active state so per-competitor pages keep the tab lit.

**Linphone** is populated as the first comparison, framed as a fair
guide (names what Linphone is genuinely good at, then the honest
differentiators: auto-record + transcription + searchable history +
guided provider setup).

## SEO & GEO

- Every page passes a real title/description, a single `<h1>`, page-type
JSON-LD referencing the org `@id`, and self-contained answers + an
extractable comparison table + a Q&A block (the structures AI answer
engines quote most).
- Copy is platform-neutral (**Mac + Linux** today, Windows later); "Mac"
stays in titles only to catch the high-volume "… for Mac" query without
excluding Linux.
- `CLAUDE.md` gains an **SEO & GEO** section codifying these conventions
for all future pages, aligned with the #81 SEO baseline.

## Testing

- `astro build` passes; `/voice/alternatives/` and
`/voice/alternatives/linphone/` generate and land in the sitemap.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
wavekat-eason pushed a commit that referenced this pull request Jun 4, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.0.27](wavekat-com-v0.0.26...wavekat-com-v0.0.27)
(2026-06-04)


### Features

* **seo:** structured data + social metadata (+ favicon & download
dropdown fixes)
([#81](#81))
([d8fb369](d8fb369))
* **voice:** add alternatives comparison pages
([#82](#82))
([6d01545](6d01545))
* **voice:** Linux download & OS-aware buttons
([#79](#79))
([590219d](590219d))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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