Issue #152 · important
Issue 152
What is this issue?
Job listing pages are missing JobPosting schema, preventing the role from appearing in Google for Jobs — the highest-intent job search placement available in SERPs.
Without JobPosting schema:
- Your job listings won't appear in Google for Jobs
- Job details (salary, employer, location, posting date) won't show in search
- Job seekers can't find your openings through Google's job search
- You'll miss out on high-intent job applicants
- Rich snippets for jobs won't display
A proper JobPosting schema should include: @type (JobPosting), title, description, datePosted, hiringOrganization, jobLocation, and optionally validThrough, baseSalary, employmentType, jobLocationType.
Why does it matter?
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
-
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: Missing JobPosting Schema on Job Listing
Problematic state:
<!-- Job listing page without 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>
Corrected state:
<!-- Job listing page with JobPosting schema -->
<html>
<head>
<title>Senior Frontend Developer - Example Corp</title>
<script type="application/ld+json">
{
"@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"
}
}
}
</script>
</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>
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
Problematic state:
{
"@context": "https://schema.org",
"@type": "JobPosting",
"title": "Marketing Manager"
}
Missing required properties: description, datePosted, hiringOrganization, jobLocation
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
PixyScan follows these logical steps to detect missing JobPosting schema:
-
Detect job pages: The crawler identifies pages with:
- URL patterns (
/careers/,/jobs/,/vacancies/,/hiring/) - Visible salary/employment type content
- Job description and requirements
- URL patterns (
-
Extract structured data: The crawler looks for JSON-LD, Microdata, or RDFa blocks on the page
-
Check for JobPosting schema: The crawler verifies if any schema block has:
@typeset toJobPosting- Required properties:
title,description,datePosted,hiringOrganization,jobLocation
-
Validate schema completeness: If JobPosting schema is found, the crawler checks for:
datePostedproperty (required by Google)hiringOrganizationproperty (required by Google)jobLocationproperty (required by Google)validThroughexpiry date (recommended)baseSalarywith range (recommended)employmentTypedeclared (recommended)
-
Trigger conditions: The issue is flagged when:
- Job listing page doesn't have JobPosting schema
- JobPosting schema exists but
datePostedis missing - JobPosting schema exists but
hiringOrganizationis missing - JobPosting schema exists but
jobLocationis missing