No JobPosting schema on a careers page
What is this issue?
This issue reports a JobPosting schema block your page already declares that is
missing title, description, datePosted or hiringOrganization — not a job
listing page that has no JobPosting schema at all.
What this issue is not:
- It does not guess. A page under
/careers/or/jobs/, showing a full job description and salary, is never reported if it declares noJobPostingschema. - It does not currently check
jobLocation, even though Google requires it for the Google for Jobs rich result — see How to fix it for why to add it anyway. - It does not check
validThrough,baseSalaryoremploymentType; these are recommended, not verified here.
Why it matters
JobPosting schema is critical for recruitment and job visibility:
- Google for Jobs: Enables job listings to appear in Google's dedicated job search interface
- Rich results: Shows salary, employer, location, and posting date in search results
- High-intent applicants: Job seekers using Google for Jobs are actively looking for work
- Visibility: Increases job listing visibility beyond traditional job boards
- AI search readiness: AI engines use JobPosting schema to answer job-related queries
- Application rates: Jobs with proper schema get more qualified applicants
Resolving this issue improves your SEO health score by ensuring job listings are properly structured for maximum visibility and applicant reach.
How to fix it
If this issue was raised, your page already declares a JobPosting missing title,
description, datePosted or hiringOrganization — open the finding for which one.
jobLocation is required by Google for the rich result even though this check does
not currently verify it, so add it regardless. The steps below are for a page that
declares no JobPosting schema yet: worthwhile to add, and never reported as a
defect while absent.
Identify job listing pages: Look for pages with:
- URL patterns (
/careers/,/jobs/,/vacancies/,/hiring/) - Visible salary/employment type content
- Job description and requirements
- URL patterns (
Add JobPosting JSON-LD structured data to the page's
<head>or before</body>:{ "@context": "https://schema.org", "@type": "JobPosting", "title": "Senior Frontend Developer", "description": "We need a React developer with 5+ years of experience...", "datePosted": "2024-03-01", "validThrough": "2024-05-01", "employmentType": "FULL_TIME", "hiringOrganization": { "@type": "Organization", "name": "Example Corp", "sameAs": "https://example.com" }, "jobLocation": { "@type": "Place", "address": { "@type": "PostalAddress", "addressLocality": "Austin", "addressRegion": "TX", "addressCountry": "US" } }, "baseSalary": { "@type": "MonetaryAmount", "currency": "USD", "value": { "@type": "QuantitativeValue", "minValue": "120000", "maxValue": "160000", "unitText": "YEAR" } } }Include required properties:
title: Job titledescription: Job description (can include HTML)datePosted: ISO 8601 date formathiringOrganization: Organization hiring for the rolejobLocation: Place or remote flag
Add recommended properties:
validThrough: Job posting expiry datebaseSalary: Salary range (use MonetaryAmount)employmentType: FULL_TIME, PART_TIME, CONTRACTOR, TEMPORARY, INTERN, VOLUNTEERjobLocationType: "TELECOMMUTE" for remote roles
Validate with Google's Rich Results Test
Examples
Example 1: No Schema Declared — Not This Issue
<!-- Job listing page with a full description, but no JobPosting schema -->
<html>
<head>
<title>Senior Frontend Developer - Example Corp</title>
</head>
<body>
<h1>Senior Frontend Developer</h1>
<p>We need a React developer with 5+ years of experience...</p>
<p><strong>Location:</strong> Austin, TX</p>
<p><strong>Type:</strong> Full Time</p>
<p><strong>Salary:</strong> $120,000 - $160,000</p>
</body>
</html>Nothing is reported, however complete the visible job listing is.
Example 1b: The Same Job, Declared and Valid (passes)
{
"@context": "https://schema.org",
"@type": "JobPosting",
"title": "Senior Frontend Developer",
"description": "We need a React developer with 5+ years of experience...",
"datePosted": "2024-03-01",
"validThrough": "2024-05-01",
"employmentType": "FULL_TIME",
"hiringOrganization": {
"@type": "Organization",
"name": "Example Corp",
"sameAs": "https://example.com"
},
"jobLocation": {
"@type": "Place",
"address": {
"@type": "PostalAddress",
"addressLocality": "Austin",
"addressRegion": "TX",
"addressCountry": "US"
}
},
"baseSalary": {
"@type": "MonetaryAmount",
"currency": "USD",
"value": {
"@type": "QuantitativeValue",
"minValue": "120000",
"maxValue": "160000",
"unitText": "YEAR"
}
}
}Example 2: Remote Job with JobPosting Schema
Corrected state for remote position:
{
"@context": "https://schema.org",
"@type": "JobPosting",
"title": "Remote SEO Specialist",
"description": "Work from anywhere as an SEO specialist...",
"datePosted": "2024-03-15",
"employmentType": "FULL_TIME",
"jobLocationType": "TELECOMMUTE",
"hiringOrganization": {
"@type": "Organization",
"name": "Example Corp"
}
}Example 3: Incomplete JobPosting Schema (fails)
Problematic state:
{
"@context": "https://schema.org",
"@type": "JobPosting",
"title": "Marketing Manager"
}Reported: description missing, datePosted missing, hiringOrganization missing. jobLocation is not part of this finding — Google requires it for the
rich result, but PixyScan's check does not currently verify it.
Corrected state:
{
"@context": "https://schema.org",
"@type": "JobPosting",
"title": "Marketing Manager",
"description": "Lead our marketing team and develop strategies...",
"datePosted": "2024-03-10",
"hiringOrganization": {
"@type": "Organization",
"name": "Example Corp"
},
"jobLocation": {
"@type": "Place",
"address": {
"@type": "PostalAddress",
"addressLocality": "New York",
"addressRegion": "NY",
"addressCountry": "US"
}
}
}How PixyScan detects this
Read the declared structured data: every JSON-LD block is parsed, and
@graphwrappers are flattened.Select declared
JobPostingentities: any schema block whose@typeisJobPosting. A page that declares none is not examined — this check does not infer a careers page from its URL (/careers/,/jobs/), visible salary text, or job-description content.Check the required properties:
title,description,datePostedandhiringOrganizationmust be present.This is reported when: the page declares a
JobPostingmissing one of those four properties. A job listing page with noJobPostingschema at all is never reported.
Note: jobLocation is not currently in the required-property list this check
enforces, even though Google requires it for the rich result — a JobPosting missing
only jobLocation passes this check today. validThrough, baseSalary and
employmentType are recommended but not checked at all.
What we store
Storage Level
Page Level — This issue is evaluated for each individual URL that contains structured data.
Database Table / Prisma Model
PageStructuredData
Stored Fields
| Field | Type | Description |
|---|---|---|
| schemaType | SchemaType | The type of schema (e.g., Organization, Person) |
| schemaFormat | SchemaFormat | The format of the schema (JSON-LD, Microdata, RDFa) |
| schemaIdentifier | String? | Unique identifier for the schema |
| rawJson | Json? | The raw JSON-LD or structured data content |
| schemaErrors | Json? | Array of validation errors found in the schema |
| isValidSchema | Boolean? | Whether the schema is valid according to validation |
| missingFields | Json? | Reserved for future use — the crawler always writes null here today; no check currently populates it |
Detection Dependencies
- The following data sources are required to evaluate this issue:
- HTML Document — The crawler parses the HTML to find structured data (JSON-LD, Microdata, RDFa)
- Structured Data Validation — The extracted schema is validated against Schema.org definitions
- Schema Parser — JSON-LD scripts, Microdata attributes, and RDFa markup are parsed