The SearchAction schema pattern most sites copy is a 2018 relic that Google deprecated in 2024. Here is the correct markup that actually triggers a Sitelinks Search Box.

EntryPoint object pattern for target is deprecated — Google's Rich Results Test flags it as an error; the correct value is a plain URL string.layout.tsx — it describes the website, not a page, so it belongs at the root layout level.SearchAction schema is the structured data type that tells Google your website has internal search — and gives it the URL pattern to use when it displays a Sitelinks Search Box directly in the SERP. When it works, users can search your site without visiting it: they type a query into the search box that appears below your homepage listing and are taken directly to your internal search results.
When it doesn't work — which is most of the time, because the markup most sites copy was deprecated in 2024 — users see nothing different and you've added invalid schema to your site's <head> for no benefit.
This guide gives you the exact current markup, explains what Google changed in 2024 and why, shows you how to implement it in Next.js and other frameworks, and tells you what to do when the schema passes validation but the search box still doesn't appear.
SearchAction is a schema.org type that represents the act of searching. In the context of a website, it tells search engines: "this site has an internal search feature, and here is the URL pattern to use for it."
When Google processes this markup and decides a site is large enough and authoritative enough, it renders a Sitelinks Search Box below the site's homepage listing in the SERP. This is the small search input field that appears directly in the results, branded with the site's name, allowing users to type a query that will take them directly to the site's search results page.
The Sitelinks Search Box has been a Google feature since 2013. The structured data that enables it has evolved — and the version most sites are still running is the version from 2018 that Google deprecated in 2024.
Before getting into the markup, it is worth being direct about who this schema is actually for:
Appropriate sites:
Not appropriate:
Google's decision to display a Sitelinks Search Box is separate from whether you have valid SearchAction markup. Even with perfect markup, Google will only show the search box for sites it considers large enough and authoritative enough to warrant it. Implementing this schema on a small site with no internal search wastes markup budget and clutters your structured data without any benefit.
The most common SearchAction schema pattern found on the web today uses an EntryPoint object for the target property. This pattern was the documented approach until Google updated its guidance in 2024. It is now deprecated and flagged as an error by Google's Rich Results Test.
The deprecated pattern — still widely copied:
{
"@context": "https://schema.org/",
"@type": "WebSite",
"url": "https://example.com/",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://example.com/search?q={search_term_string}"
},
"query-input": "required name=search_term_string"
}
}
This markup appears in thousands of blog posts, StackOverflow answers, and WordPress plugin documentation written before 2024. When developers copy it today, they are implementing markup that Google's validator will flag with an error.
The specific problem: target should be a URL string or a subtype of Intangible that has a direct URL value. Using EntryPoint as the value — which itself only has urlTemplate, not a direct URL — creates an indirection that Google's updated parser no longer accepts.
The fix is straightforward: target should be a plain URL string with the {search_term_string} placeholder inline, not an EntryPoint object wrapper.
The correct current markup:
{
"@context": "https://schema.org/",
"@type": "WebSite",
"url": "https://example.com/",
"potentialAction": {
"@type": "SearchAction",
"target": "https://example.com/search?q={search_term_string}",
"query-input": "required name=search_term_string"
}
}
The differences from the deprecated pattern:
| Property | Deprecated | Current |
|---|---|---|
target value type |
EntryPoint object |
Plain URL string |
| URL template location | Inside EntryPoint.urlTemplate |
Directly in target |
query-input |
Same | Same (unchanged) |
@context |
https://schema.org |
https://schema.org/ (trailing slash) |
The query-input property remains unchanged: "required name=search_term_string" tells Google that the {search_term_string} placeholder in the URL template is a required parameter supplied by the user's search query. Do not change this value.
The {search_term_string} placeholder in the URL string is not a standard JavaScript template literal — it is a schema.org-specific annotation that tells Google where to insert the user's query. Leave the curly braces and exact string as shown; do not URL-encode them.
Here is the full, production-ready SearchAction markup with the correct current pattern, using seo.yatna.ai as the example site:
{
"@context": "https://schema.org/",
"@type": "WebSite",
"name": "seo.yatna.ai",
"url": "https://seo.yatna.ai/",
"potentialAction": {
"@type": "SearchAction",
"target": "https://seo.yatna.ai/search?q={search_term_string}",
"query-input": "required name=search_term_string"
}
}
The name property on the WebSite type is optional but recommended — it gives Google a human-readable label for the search box that appears in the SERP, separate from the domain name. Use your brand name or product name, not a keyword-stuffed phrase.
The url property must match the canonical homepage URL exactly, including the trailing slash if your site uses it. A mismatch between the url value and your site's actual canonical URL can prevent Google from associating the markup with the correct domain.
SearchAction schema describes the website itself, not any individual page. This means it belongs in your root layout — app/layout.tsx — not in any page-level component. Adding it to layout.tsx ensures it appears on every page render, which is appropriate for site-level markup.
// app/layout.tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
// ... your existing metadata
}
const searchActionSchema = {
"@context": "https://schema.org/",
"@type": "WebSite",
"name": "seo.yatna.ai",
"url": "https://seo.yatna.ai/",
"potentialAction": {
"@type": "SearchAction",
"target": "https://seo.yatna.ai/search?q={search_term_string}",
"query-input": "required name=search_term_string"
}
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(searchActionSchema) }}
/>
</head>
<body>{children}</body>
</html>
)
}
The searchActionSchema constant is defined at module scope as a server-side value — it never contains user input. The dangerouslySetInnerHTML call is safe in this context for the same reason it is safe for all server-generated JSON-LD: the content is a hardcoded constant, not a string assembled from request parameters or database values.
If your site's search URL includes additional parameters beyond q, include them as static parameters in the target URL string. Only the value that maps to the user's search term should use the {search_term_string} placeholder:
"target": "https://seo.yatna.ai/search?q={search_term_string}&type=posts"
Astro
In Astro, add the schema to your base layout component inside the <head> block:
---
// layouts/BaseLayout.astro
const searchSchema = JSON.stringify({
"@context": "https://schema.org/",
"@type": "WebSite",
"name": "Your Site Name",
"url": "https://yoursite.com/",
"potentialAction": {
"@type": "SearchAction",
"target": "https://yoursite.com/search?q={search_term_string}",
"query-input": "required name=search_term_string"
}
});
---
<html>
<head>
<script type="application/ld+json" set:html={searchSchema} />
</head>
<body>
<slot />
</body>
</html>
WordPress
Add the following to your theme's functions.php or a site-specific plugin. Unlike FAQPage schema which is page-specific, SearchAction schema should be output on every page (or at minimum the homepage) since it describes the site:
function add_searchaction_schema() {
$schema = array(
'@context' => 'https://schema.org/',
'@type' => 'WebSite',
'name' => get_bloginfo( 'name' ),
'url' => home_url( '/' ),
'potentialAction' => array(
'@type' => 'SearchAction',
'target' => home_url( '/' ) . 'search?q={search_term_string}',
'query-input' => 'required name=search_term_string',
),
);
echo '<script type="application/ld+json">'
. wp_json_encode( $schema )
. '</script>' . "\n";
}
add_action( 'wp_head', 'add_searchaction_schema' );
Adjust the target URL to match your WordPress search URL structure. WordPress default search uses /?s={search_term_string}. If you use a custom search solution with a different URL pattern, update the target value accordingly.
Correct schema markup is necessary but not sufficient. Google applies several additional criteria before displaying a Sitelinks Search Box:
1. Your site must have working internal search
The URL template in target must resolve to a real search results page when a query is substituted. If https://yoursite.com/search?q=test returns a 404, an empty page, or a generic page that doesn't change based on the query, Google will not display the search box.
2. Google must consider your site authoritative enough
Google does not publish the authority threshold. In practice, Sitelinks Search Boxes are visible for established brands, large SaaS products, major media publishers, and e-commerce sites with significant traffic. A site that launched recently or has limited backlink authority is unlikely to receive the feature regardless of schema quality.
3. The search must return relevant results
Google may evaluate the quality of your search results by following the URL template with test queries. Search that returns obviously irrelevant results, or results that are not usefully ordered by relevance, reduces the likelihood of display.
4. No manual action against your structured data
If your site has received a manual action for structured data abuse in any other schema type, it can suppress all rich results including the Sitelinks Search Box until the action is resolved.
After deploying your markup, validate it at search.google.com/test/rich-results:
potentialAction appears in the detected properties, with target shown as a URL string (not an EntryPoint object)If the test shows an error about target, you are likely using the deprecated EntryPoint pattern. Replace the target object with a plain URL string as shown in the correct example above.
If the test shows no errors but the search box does not appear in your actual SERP listing, the issue is not the markup — it is Google's site authority threshold. There is no action to take other than continuing to build site quality. The schema is correct and will be processed when Google considers the site eligible.
Google Search Console's Enhancements section includes a "Sitelinks Searchbox" report when Google has detected your SearchAction markup. This report is more informative than the Rich Results Test for diagnosing why the search box is not displaying.
Common errors in the Sitelinks Searchbox report:
"Missing field 'potentialAction'"
The WebSite type has been detected but there is no potentialAction property. This usually means the schema is incomplete — check that the potentialAction key exists at the correct level of the JSON object (directly inside the WebSite object, not nested inside another property).
"Invalid value for 'target'"
This is the deprecated EntryPoint pattern error. Fix: replace the EntryPoint object with a plain URL string.
"Unparsable structured data"
The JSON-LD itself is malformed — a missing comma, an unescaped quote, or an unclosed brace. Use a JSON validator (jsonlint.com or the Rich Results Test code input) to find the syntax error.
"Page not eligible for rich result"
This appears when the markup is technically valid but Google has determined the page or site does not meet the quality threshold for display. There is no schema fix for this — it reflects a site authority or quality assessment that can only be resolved by improving the site itself.
No report at all
If SearchAction markup has been deployed for several weeks and no Sitelinks Searchbox report appears in Search Console, check that Googlebot is crawling the page with the schema, that the schema is present in the server-rendered HTML (not injected client-side after load), and that the page is not blocked by robots.txt or a noindex directive.
| Mistake | Cause | Fix |
|---|---|---|
Using EntryPoint object for target |
Copying 2018 documentation | Use a plain URL string |
{search_term_string} URL-encoded |
Build tool or template engine encodes it | Add markup to a raw string, not a URL builder function |
| Schema only on homepage | Logical but unnecessary restriction | Schema in layout.tsx appears on all pages |
| Search URL returns 404 | Search not implemented or wrong URL pattern | Verify target URL with a real query manually |
Missing trailing slash on url |
Inconsistency with canonical | Match exactly the canonical homepage URL |
Schema in generateMetadata |
Next.js App Router misunderstanding | Move to a <script> tag in the layout component |
Does SearchAction schema improve rankings?
No. SearchAction schema does not influence organic rankings. It controls whether a Sitelinks Search Box appears beneath your homepage listing in the SERP. Its value is in user experience and click-through behaviour — users who use the search box arrive at highly relevant pages on your site, which can indirectly improve behavioural signals.
Can I use SearchAction schema on a site without internal search?
You can implement it, but Google will not display the Sitelinks Search Box if the target URL does not return meaningful search results. Do not add SearchAction schema as a cargo-cult practice without a working search implementation.
Should the url in WebSite schema match my homepage exactly?
Yes. The url value should match your canonical homepage URL — including or excluding the trailing slash, www or non-www, and https vs http — exactly as it appears in your canonical tags and sitemap. A mismatch can prevent Google from associating the schema with the correct property in Search Console.
My markup passes validation but the search box doesn't appear. What do I do?
Wait and continue building site authority. The Sitelinks Search Box is Google's discretionary feature — valid markup is a prerequisite, not a guarantee. Sites that receive it typically have significant organic traffic, strong brand search volume, and well-established authority in their category. There is no specific action beyond maintaining correct markup and continuing normal SEO work.
Can I specify multiple search actions for different content types?
Schema.org technically allows an array for potentialAction, but Google's Sitelinks Search Box implementation processes only one SearchAction. Using a single, primary search action pointing to your main search is the correct approach.
Check that your markup uses the current target string pattern — not the deprecated EntryPoint object — before Googlebot processes it:
Validate your SearchAction schema — free schema checker at seo.yatna.ai/tools/schema-validator
The validator confirms that target is a plain URL string, that {search_term_string} appears correctly in the URL, that query-input has the required format, and that no deprecated properties are present — catching the full set of errors that cause the Sitelinks Search Box to be suppressed.
For implementation help with other schema types, see the SoftwareApplication schema guide and the FAQPage schema guide.
About the Author

Ishan Sharma
Head of SEO & AI Search Strategy
Ishan Sharma is Head of SEO & AI Search Strategy at seo.yatna.ai. With over 10 years of technical SEO experience across SaaS, e-commerce, and media brands, he specialises in schema markup, Core Web Vitals, and the emerging discipline of Generative Engine Optimisation (GEO). Ishan has audited over 2,000 websites and writes extensively about how structured data and AI readiness signals determine which sites get cited by ChatGPT, Perplexity, and Claude. He is a contributor to Search Engine Journal and speaks regularly at BrightonSEO.