Skip to content

Fix duplicate title, meta description, and canonical tags detected by Bing SEO audit #337

Description

@arii

Problem

Bing Webmaster Tools / SEO audit flagged the following errors and notices:

  1. Error: More than one <title> tag (2 instances found)
  2. Error: More than one Meta Description tag (<meta name="description">, 2 instances found)
  3. Notice: More than one canonical tag (<link rel="canonical">, 2 instances found)

Root Cause Analysis

  • Static vs Client-Side Hydration (Helmet):
    • Static HTML files (index.html and SPA route stubs generated by scripts/generate-spa-stubs.js) output static <title>, <meta name="description">, and <link rel="canonical"> elements.
    • When React mounts on the client side, react-helmet-async (src/components/SEO.tsx) injects its own <meta> and <link> tags into the <head>.
    • Without data-rh="true" attributes on prerendered tags, Helmet cannot associate existing head tags with its managed state, causing it to append duplicate DOM nodes when JS executes during crawler rendering.

Critical Requirements & Constraints

Important

Do NOT undo per-route unique metadata:

  • In previous iterations, generic Vite SPA fallback workarounds caused all child routes to get overwritten with the homepage/root metadata.
  • Every individual route (/about, /research/*, /devai/, /demos/*, etc.) must retain its unique seoTitle, seoDescription, canonical URL, and structured JSON-LD generated from its markdown frontmatter and route discovery.
  • Tag deduplication must be achieved by aligning Helmet hydration (adding data-rh="true" attributes on prerendered static tags), NOT by removing per-route static prerendering or falling back to a single generic template.

Action Items

  • Tag Deduplication via Helmet Alignment:
    • Add data-rh="true" attributes to all prerendered static <title>, <meta name="description">, <link rel="canonical">, and OG/Twitter tags in index.html and scripts/generate-spa-stubs.js.
  • Preserve Per-Route Unique Metadata:
    • Verify that each static HTML stub preserves unique titles, descriptions, canonical URLs, and structured JSON-LD per route.
  • Automated Head Tag Tests:
    • Add unit and E2E/Playwright test assertions to verify that:
      1. Exactly 1 <title>, 1 <meta name="description">, and 1 <link rel="canonical"> exist in the DOM post-hydration.
      2. Route navigation properly updates metadata and maintains unique per-route values.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions