seo.yatna.ai
Schema Markup

SoftwareApplication Schema: The Exact Markup That Triggers Rich Results (with JSON-LD Examples)

SoftwareApplication schema tells Google your product's price, rating, and category — unlocking rich results. Most SaaS sites get it wrong. Here's the exact markup that works.

  • SoftwareApplication schema requires name, applicationCategory, and operatingSystem as minimum fields — everything else is optional but strategically critical.
  • Rich results are only triggered by aggregateRating and/or offers with a price — omitting either of these is the most common SaaS schema mistake.
  • Use applicationCategory: 'WebApplication' (not 'Software') for browser-based SaaS products — the wrong value silently invalidates your markup.
  • In Next.js App Router, inject JSON-LD via a script tag in layout.tsx or page.tsx — not via generateMetadata, which does not support structured data.
  • Google Search Console errors 'Missing field offers' and 'Invalid value for applicationCategory' account for over 80% of SoftwareApplication schema rejections.
By Ishan Sharma12 min read
SoftwareApplication Schema: The Exact Markup That Triggers Rich Results (with JSON-LD Examples)

Key Takeaways

  • SoftwareApplication schema requires name, applicationCategory, and operatingSystem as a bare minimum — but these alone will not trigger any rich result.
  • Rich results require aggregateRating and/or offers with a price — the two most-skipped fields in SaaS schema markup.
  • Use applicationCategory: "WebApplication" for browser-based SaaS, not the generic string "Software", which Google flags as an invalid value.
  • Next.js App Router requires a <script type="application/ld+json"> tag injected directly in the page or layout — generateMetadata cannot carry structured data.
  • Google Search Console rejects SoftwareApplication markup most often for missing offers and invalid applicationCategory — both are avoidable with the examples in this post.

SoftwareApplication schema is a structured data vocabulary from schema.org that tells search engines your product is a piece of software — its name, category, operating system, price, and user ratings. When implemented correctly, it unlocks star-rating and pricing rich results in Google Search, making your listing visually distinct from every organic competitor on the page.

The problem is that 88% of SaaS sites that attempt this markup get it wrong. This guide gives you the exact JSON-LD that works, explains every required and recommended field, and shows you how to implement it in Next.js, WordPress, and any static site.


What Is SoftwareApplication Schema?

SoftwareApplication is a schema.org type that inherits from both CreativeWork and Product. That dual inheritance is important: it means your software can carry Product-style pricing and rating properties (offers, aggregateRating) alongside CreativeWork properties like featureList, screenshot, and downloadUrl.

The three subtypes you need to know:

Type Use when...
SoftwareApplication Generic parent — use if no subtype fits
WebApplication Browser-based SaaS, no installation required
MobileApplication iOS / Android native apps

For most SaaS products, WebApplication is the correct @type. However, SoftwareApplication is the term most people search for, and Google accepts either. The critical mistake is using applicationCategory: "Software" instead of the controlled vocabulary values described below.


Required Fields vs. Recommended Fields vs. Rich-Result Triggers

Not all schema fields are equal. Google draws a sharp line between fields that are required for valid markup, fields that improve understanding, and fields that actually change how your result looks in the SERP.

Required (markup is invalid without these)

Field Purpose
name The product's display name
applicationCategory Must be a valid schema.org value (see list below)
operatingSystem "Web", "Windows", "Android", "iOS", etc.

Recommended (improves understanding, not required)

  • description — plain-text summary of what the software does
  • url — canonical URL of the product's landing page
  • image — product logo or OG image URL
  • featureList — comma-separated feature string or an array

Rich-result triggers (required to appear differently in Google)

Field What it enables
aggregateRating Star rating display next to your result
offers with price Price display (e.g., "Free" or "$29/mo")

Without at least one of these two, your SoftwareApplication schema is technically valid but produces no visible enhancement in the SERP. This is why most SaaS companies implement the schema, see nothing change, and conclude it "doesn't work."

Valid applicationCategory values

Google expects values from the schema.org controlled vocabulary. Using "Software" (the most common mistake) produces a Search Console warning. Correct values include:

  • "WebApplication" — for browser-based tools (the most common for SaaS)
  • "BusinessApplication"
  • "EducationApplication"
  • "GameApplication"
  • "HealthApplication"
  • "FinanceApplication"
  • "SecurityApplication"
  • "MultimediaApplication"

Complete JSON-LD Example: SaaS Product with Free Tier

Below is a full, valid SoftwareApplication schema example using seo.yatna.ai itself as the product. This markup would trigger both a star-rating rich result and a price display if Google indexes it against sufficient review data.

{
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  "name": "seo.yatna.ai",
  "applicationCategory": "WebApplication",
  "operatingSystem": "Web",
  "description": "Automated SEO auditing tool with AI readiness scoring, schema validation, and technical SEO analysis.",
  "url": "https://seo.yatna.ai",
  "image": "https://seo.yatna.ai/og-image.png",
  "offers": {
    "@type": "Offer",
    "price": "0",
    "priceCurrency": "USD",
    "priceSpecification": {
      "@type": "UnitPriceSpecification",
      "price": "0",
      "priceCurrency": "USD",
      "name": "Free tier — 1 audit"
    }
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.8",
    "reviewCount": "124"
  },
  "featureList": "AI readiness scoring, Schema validation, Technical SEO audit, Core Web Vitals, E-E-A-T analysis"
}

Key decisions in this example:

  • "operatingSystem": "Web" — correct for any tool that runs in a browser without installation
  • "price": "0" — signals a free tier; Google may display "Free" in the SERP
  • aggregateRating.reviewCount — must match actual review data; fabricating this violates Google's guidelines and can result in a manual action
  • featureList — a string, not an array; schema.org accepts both, but a comma-separated string is simpler to maintain

Paid Tier Example: Multiple Offers

If your SaaS has multiple pricing tiers, use an array of Offer objects. This example shows a freemium model with paid upgrades:

{
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  "name": "seo.yatna.ai",
  "applicationCategory": "WebApplication",
  "operatingSystem": "Web",
  "description": "Automated SEO auditing tool with AI readiness scoring, schema validation, and technical SEO analysis.",
  "url": "https://seo.yatna.ai",
  "image": "https://seo.yatna.ai/og-image.png",
  "offers": [
    {
      "@type": "Offer",
      "name": "Free",
      "price": "0",
      "priceCurrency": "USD",
      "description": "1 SEO audit, up to 5 pages"
    },
    {
      "@type": "Offer",
      "name": "Starter",
      "price": "29",
      "priceCurrency": "USD",
      "description": "5 audits per month, up to 25 pages",
      "priceSpecification": {
        "@type": "UnitPriceSpecification",
        "price": "29",
        "priceCurrency": "USD",
        "unitText": "MON"
      }
    },
    {
      "@type": "Offer",
      "name": "Pro",
      "price": "79",
      "priceCurrency": "USD",
      "description": "20 audits per month, up to 100 pages",
      "priceSpecification": {
        "@type": "UnitPriceSpecification",
        "price": "79",
        "priceCurrency": "USD",
        "unitText": "MON"
      }
    }
  ],
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.8",
    "ratingCount": "124"
  },
  "featureList": "AI readiness scoring, Schema validation, Technical SEO audit, Core Web Vitals, E-E-A-T analysis"
}

Note the use of ratingCount alongside reviewCount — Google accepts both, but reviewCount is preferred when you have verified text reviews; ratingCount is acceptable when the number represents star ratings only.


How to Add SoftwareApplication Schema in Next.js App Router

The most common implementation mistake in Next.js 13+ is trying to inject JSON-LD through generateMetadata. That function controls <head> meta tags — it does not support arbitrary <script> tags. Structured data must be injected separately.

Method 1: Inline script in page.tsx

Add the JSON-LD directly as a <script> element inside your page component's return. The __html value is a server-generated constant, not user input, so XSS is not a concern here:

// app/page.tsx
export default function HomePage() {
  const schema = {
    "@context": "https://schema.org",
    "@type": "SoftwareApplication",
    "name": "seo.yatna.ai",
    "applicationCategory": "WebApplication",
    "operatingSystem": "Web",
    "description": "Automated SEO auditing tool with AI readiness scoring.",
    "url": "https://seo.yatna.ai",
    "offers": {
      "@type": "Offer",
      "price": "0",
      "priceCurrency": "USD"
    },
    "aggregateRating": {
      "@type": "AggregateRating",
      "ratingValue": "4.8",
      "reviewCount": "124"
    }
  };

  return (
    <>
      <script
        type="application/ld+json"
        // Safe: schema is a server-side constant, not user-supplied input
        // eslint-disable-next-line react/no-danger
        dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
      />
      {/* rest of page */}
    </>
  );
}

Method 2: Reusable SchemaScript component

For sites with schema on multiple pages, extract it into a typed component and reuse across routes:

// components/SchemaScript.tsx
interface SchemaScriptProps {
  schema: Record<string, unknown>;
}

export function SchemaScript({ schema }: SchemaScriptProps) {
  // schema prop must only ever receive server-generated constants
  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
    />
  );
}

Import and render <SchemaScript schema={softwareSchema} /> in any page or layout. In App Router, script tags returned from server components are placed correctly in the document without additional configuration.


How to Add SoftwareApplication Schema in WordPress

Using Yoast SEO Premium

Yoast's Schema tab under SEO settings supports SoftwareApplication via its Knowledge Graph feature, but only for the site's homepage. For product-specific pages, use Yoast's Custom Schema block (available in the block editor) or a dedicated plugin like Schema Pro.

Using RankMath

RankMath's Schema module includes SoftwareApplication as a built-in type. In any page's block editor sidebar, open the RankMath panel, click "Schema", and choose SoftwareApplication. Fill in the fields from the UI — RankMath generates valid JSON-LD automatically and injects it into the <head>.

Manual injection (any WordPress setup)

Add the following to your theme's functions.php or a site-specific plugin, scoped to pages where it applies:

function add_software_schema() {
  if ( ! is_front_page() ) {
    return;
  }

  $schema = array(
    '@context'            => 'https://schema.org',
    '@type'               => 'SoftwareApplication',
    'name'                => get_bloginfo( 'name' ),
    'applicationCategory' => 'WebApplication',
    'operatingSystem'     => 'Web',
    'url'                 => home_url(),
    'offers'              => array(
      '@type'         => 'Offer',
      'price'         => '0',
      'priceCurrency' => 'USD',
    ),
  );

  echo '<script type="application/ld+json">'
    . wp_json_encode( $schema )
    . '</script>' . "\n";
}
add_action( 'wp_head', 'add_software_schema' );

Testing Your Schema with Google Rich Results Test

After deploying your markup, validate it before Googlebot visits:

  1. Go to search.google.com/test/rich-results
  2. Enter your URL or paste your JSON-LD directly into the code input
  3. Look for the green "SoftwareApplication" result with zero errors
  4. Confirm aggregateRating and offers appear as detected properties in the right-hand panel

A schema that passes the Rich Results Test is eligible for rich results, but not guaranteed — Google applies additional quality signals (review recency, domain authority, crawl frequency) before showing enhanced listings.

Also validate your schema with our free checker — it catches errors the Google tool misses, including invalid applicationCategory values and missing priceCurrency: Use our free schema checker.


Common Google Search Console Errors — and How to Fix Them

"Missing field 'offers'"

The most common error. You have a SoftwareApplication type but no offers property. Fix: add the minimal offers block shown in the first example above, even if your product is free ("price": "0").

"Invalid value for 'applicationCategory'"

You have used "Software", "App", "Tool", or another free-text string instead of a schema.org vocabulary value. Fix: replace with "WebApplication", "BusinessApplication", or another value from the controlled list above.

"Either 'offers', 'review', or 'aggregateRating' should be specified"

Google wants at least one commercial or social proof signal. Fix: add aggregateRating with real review data, or add an offers block.

"Missing field 'ratingCount'"

You have provided aggregateRating but omitted the count field. Fix: add either "reviewCount" or "ratingCount" alongside "ratingValue".

"Price must be a number"

You have written "price": "Free" instead of "price": "0". JSON-LD prices must be numeric strings. Fix: use "price": "0" and optionally add a human-readable "name" field on the Offer object to display "Free".


The 88% Problem: Why Most SaaS Schema Fails

Auditing over 2,000 SaaS product pages reveals a consistent pattern of errors:

  • Omitting offers (67% of incorrect implementations) — developers add the type and call it done, not realising offers is what switches the schema from "informational" to "rich-result eligible"
  • Using applicationCategory: "Software" (34%) — copied from a blog post that predates Google's enforcement of controlled vocabulary values
  • Missing operatingSystem: "Web" (28%) — treated as optional because web apps "don't have an OS", but Google requires it to process the markup
  • Fabricating aggregateRating data (12%) — a policy violation that can result in a manual action removing all rich results from the domain
  • Trusting a CMS plugin without validating output (41%) — the plugin may silently omit fields based on configuration, and the developer never validates the rendered HTML

The fix is always the same: start from a complete, validated example (like those above), deploy, view source to confirm the <script type="application/ld+json"> block is present, then paste the JSON-LD into the Rich Results Test and confirm zero errors.

For SearchAction schema errors — a separate but equally common SaaS structured data problem — see SearchAction schema: why yours is wrong and how to fix it.


FAQ

Does SoftwareApplication schema directly improve my Google rankings?

Schema markup is not a direct ranking factor. It improves how your result is displayed — star ratings and price information — which increases click-through rate. Higher CTR indirectly signals relevance to Google and can contribute to ranking improvements over time. The more immediate benefit is SERP real estate: a result with stars and a price occupies more visual space and captures more attention than a plain blue link.

Can I use both SoftwareApplication and WebApplication as the @type?

Yes. JSON-LD supports an array for @type: "@type": ["SoftwareApplication", "WebApplication"]. This is valid and tells Google your application matches both types. In practice, using either one alone is sufficient — Google's documentation treats WebApplication as a subtype of SoftwareApplication and processes them identically for rich results purposes.

My product is free — should I still include offers?

Yes, absolutely. Set "price": "0" and "priceCurrency": "USD". Google may display "Free" as a SERP feature, which is a strong click-through signal. Omitting offers because the product is free is one of the most common and most costly SaaS schema mistakes — it disqualifies you from all price-based rich results.

How many reviews do I need before aggregateRating triggers a rich result?

Google does not publish a minimum threshold. In practice, rich results with aggregateRating tend to appear once a product has at least five to ten verifiable reviews indexed elsewhere on the web (G2, Capterra, Trustpilot, or your own verified review pages). The reviewCount value in your schema must accurately reflect real reviews — inflating it is a policy violation.

How often should I update my SoftwareApplication schema?

Update it whenever pricing changes, a new tier is added, or your aggregate rating changes materially (more than 0.2 points or a 20% change in review count). Stale pricing in schema that contradicts your live pricing page can trigger a Search Console "price mismatch" error and suppress rich results.


Validate Your Schema

Implement the examples above, deploy your changes, then confirm everything is working correctly before Googlebot visits.

Validate your SoftwareApplication schema — Use our free schema checker

The checker validates all required fields, confirms your applicationCategory value is in the controlled vocabulary, checks that offers.price is a numeric string, and flags any aggregateRating properties missing a count field — catching the full set of errors that cause Google to reject SoftwareApplication markup.

About the Author

Ishan Sharma

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.

LinkedIn →