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
SITEconfig 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=testafter 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.
Related
Tags: #SEO #Troubleshooting #Debug #Structured data #WebSite schema #JSON-LD