Files
CompanySite/.agents/seo-specialist/THEME_SEO_UPDATE.md
T
Clintchiz 0614ae6f85
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
Deploy to Production / Build & Verify (push) Failing after 13s
Ping Search Engines / Notify Search Engines (push) Successful in 3s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 1s
E2E Test Suite / Smoke Tests (P0) (push) Failing after 9m36s
E2E Test Suite / Form Interaction Tests (push) Failing after 12m6s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 11m46s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 9m31s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 11m5s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 15m24s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 6s
E2E Test Suite / Mobile Device Tests (push) Failing after 3h12m28s
Uptime Monitor / Health & Response Time (push) Successful in 5s
Uptime Monitor / SSL Certificate (push) Successful in 3s
Uptime Monitor / Send Alerts (push) Has been skipped
Uptime Monitor / Record Uptime Success (push) Successful in 2s
Latest Updated Pages
2026-03-22 14:37:17 +05:30

3.7 KiB

SEO Theme Support Update

Date: 2026-03-21 Agent: seo-specialist Task: Update SEO metadata for theme support


Summary of Changes

1. src/layouts/BaseLayout.astrotheme-color meta tags

Before:

<meta name="theme-color" content="#0891b2" />

After:

<!-- OS-level dual media query approach -->
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#0891b2" />
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#0f172a" />

The dual media attribute approach lets browsers natively use the correct browser-chrome color based on OS theme — even before JavaScript runs. This is important for users who haven't yet interacted with the site.

The inline theme-init script (already present for FOUC prevention) was extended to also sync these meta tags when a user has a stored explicit preference in localStorage that overrides their OS setting.


2. src/components/ThemeToggle.astro — Meta tag sync on toggle

Before: applyTheme() used querySelector (selects only the first meta), and the system-preference change listener did not update theme-color at all.

After:

  • applyTheme() uses querySelectorAll('meta[name="theme-color"]').forEach(...) to update all theme-color metas simultaneously
  • System preference change listener (matchMedia change event) now also syncs all theme-color metas when no stored preference exists

What Was NOT Changed (and Why)

Structured Data (JSON-LD)

All schema.org structured data in BaseLayout.astro and SEO.astro is theme-agnostic by design. JSON-LD describes content/entities, not visual presentation. Search engines and AI crawlers have no concept of visual theme when consuming structured data. No changes needed.

Open Graph / Twitter Card Images

Social preview images (og-image.jpg) are static assets served to social crawlers and link-unfurling bots. These crawlers:

  • Do not respect OS prefers-color-scheme
  • Do not execute JavaScript
  • Do not honor media query attributes

Providing separate dark/light OG images would require serving different <meta property="og:image"> values based on the server-side request context, which adds complexity without meaningful SEO benefit. The existing og-image.jpg works universally.

Other Meta Tags

All other meta tags (title, description, canonical, robots, OG/Twitter properties) are theme-agnostic and correct as-is.


Color Values Used

Theme theme-color value Token
Light #0891b2 --palette-primary-500 (brand cyan)
Dark #0f172a --color-surface dark (deep navy)

These values match the design tokens in src/styles/design-tokens.css.


How It Works End-to-End

  1. Page load (no JS yet): Browser reads both theme-color meta tags and picks the one matching OS preference via the media attribute — instant, no flash.
  2. Inline init script fires: If user has a stored preference that differs from OS, the script updates both meta tag content values to the stored preference color.
  3. User clicks ThemeToggle: applyTheme() toggles the .dark class AND updates all theme-color metas in one synchronous call.
  4. User changes OS theme (no stored preference): matchMedia change listener updates .dark class AND syncs all theme-color metas.

Testing

Verify correct behavior by:

  1. Opening DevTools → Elements → search for theme-color meta tags
  2. Toggle between light/dark using the site toggle — both meta content values should update to the same color
  3. Remove localStorage theme key, change OS theme — meta tags should track OS preference
  4. Check browser tab/address bar color updates on Chrome/Edge (Android) after toggle