WebSite JSON-LD Does Not Match the Actual Site

The site-level WebSite JSON-LD declares name / URL / SearchAction that don't match reality. Why this confuses Google and how to align it.

You search Google for your brand and the sitelinks search box doesn’t appear, or the knowledge panel uses a slightly different version of your site name than you’d expect. View source of your homepage shows a WebSite JSON-LD block with values that don’t quite match the visible site: name says “My AI Site” but the logo and footer say “AI Productivity Guide.” potentialAction.target.urlTemplate points to /?q={search_term_string} but your search endpoint is actually /search?query=. Google reads WebSite JSON-LD as a high-trust signal for sitelinks search, site name, and brand identity — but only when values match reality.

Common causes

Ordered by hit rate, highest first.

1. name uses old / placeholder brand

Starter template shipped with name: "My Site" and you never updated it. Or you rebranded but the JSON-LD generator wasn’t updated.

How to spot it:

curl -s https://yoursite.com/ | grep -oP '"@type":"WebSite"[\s\S]+?</script>' | grep -oP '"name":"\K[^"]+'

If different from your visible logo/footer name, this is it.

2. url has trailing slash mismatch with canonical

JSON-LD: "url": "https://yoursite.com". Canonical: "https://yoursite.com/". Google sees two slightly different URLs claimed as the site root.

How to spot it: Compare WebSite.url to your homepage canonical. Should be byte-identical.

3. potentialAction URL template points to a non-existent endpoint

"potentialAction": {
  "@type": "SearchAction",
  "target": "https://yoursite.com/?q={search_term_string}"
}

But your actual search URL is /search/?query=foo. Google tests the template by submitting a sample search; if it 404s or doesn’t return search results, the SearchAction is ignored.

How to spot it:

curl -sI "https://yoursite.com/?q=test"  # Should return 200 with search results

If 404, your template is wrong.

4. inLanguage doesn’t match <html lang>

JSON-LD: "inLanguage": "en". HTML: <html lang="en-US">. Should be aligned.

How to spot it:

curl -s https://yoursite.com/ | grep -oE '<html[^>]+lang="[^"]+"|"inLanguage":"[^"]+"'

5. Multiple WebSite blocks on the same page

Some templates emit WebSite from a layout file AND from a separate site-level schema component. Google sees 2 blocks for the same WebSite — confusion.

How to spot it:

curl -s https://yoursite.com/ | grep -c '"@type":"WebSite"'

1 = duplicate. Pick one source, remove the other.

6. WebSite JSON-LD on every page instead of just homepage

Strictly not “incorrect,” but wasteful. Best practice is to emit it only on the homepage; site-internal pages don’t need it.

How to spot it: Check JSON-LD on a non-homepage article. If WebSite is there, it’s redundant.

7. @id differs from URL

"@id": "https://yoursite.com#website" is fine. "@id": "https://oldsite.com/#website" is not — old domain reference.

How to spot it: Check @id for legacy domain or wrong format.

Shortest path to fix

Step 1: Define one source of truth

In site.config.mjs or equivalent:

export const SITE = {
  name: "AI Productivity Guide",
  url: "https://yoursite.com",
  searchUrlTemplate: "https://yoursite.com/search?query={search_term_string}",
  inLanguage: "en",  // or "en-US" matching <html lang>
};

Step 2: Generate WebSite JSON-LD from it

Only on the homepage:

---
import { SITE } from '../site.config.mjs';
const isHomepage = Astro.url.pathname === '/' || Astro.url.pathname === '/en/';
---
{isHomepage && (
  <script type="application/ld+json" set:html={JSON.stringify({
    "@context": "https://schema.org",
    "@type": "WebSite",
    "@id": `${SITE.url}#website`,
    "url": SITE.url,
    "name": SITE.name,
    "inLanguage": SITE.inLanguage,
    "potentialAction": {
      "@type": "SearchAction",
      "target": {
        "@type": "EntryPoint",
        "urlTemplate": SITE.searchUrlTemplate,
      },
      "query-input": "required name=search_term_string",
    },
  })}></script>
)}

Step 3: Verify the search endpoint works

curl -sI "https://yoursite.com/search?query=test" | head -1

Must return 200. The page must actually show search results for the query parameter.

Step 4: Align visible elements

<title> of homepage, logo alt text, footer site name, schema.org name — all four must match exactly.

Step 5: Remove duplicate WebSite blocks

grep -rn 'WebSite' src/layouts src/components

Keep one source. Delete the rest.

Step 6: Test in Rich Results Test

After deploy, open homepage in Rich Results Test. Should detect WebSite type with SearchAction.

Step 7: Wait and watch

Sitelinks search box appearance is at Google’s discretion. After fix, it may take weeks to months for the box to appear (or it may never appear — Google has reduced these features). Don’t expect overnight.

When this is not on you

Even with perfect WebSite JSON-LD, the sitelinks search box has been quietly reduced by Google in recent years for most non-major sites. Don’t expect rich features for a small site even with perfect markup.

Easy to misdiagnose as

Adding WebSite JSON-LD on every page (instead of just the homepage) is unnecessary and increases payload. Google only reads it from the homepage anyway.

Prevention

  • Single SITE config source for name, URL, and search endpoint.
  • Emit WebSite JSON-LD only on the homepage (or the locale’s homepage for bilingual sites).
  • Verify the search endpoint actually returns 200 with results for ?q=test after any URL routing change.
  • CI assertion that homepage has exactly one WebSite block.
  • Update WebSite JSON-LD whenever you rebrand or change the search endpoint URL.

FAQ

  • Can I declare multiple WebSite blocks? Only one per page; Google ignores or merges the rest.
  • Is SearchAction guaranteed to display? No — Google decides per query and per site authority.

Tags: #SEO #Troubleshooting #Debug #Structured data #WebSite schema #JSON-LD