Job posting schema is a block of JSON-LD in a job page’s HTML that tells Google the job’s title, employer, location, pay and deadline in a form it can read directly. On WordPress, you either write it by hand, use an SEO plugin that supports it, or run a job board plugin that outputs it for you. WP Career Board does the last one: every open job gets a JobPosting block, built from the same data the REST API returns.
One caution up front. Markup is a requirement for being considered, not a promise. Nobody can guarantee a job appears in Google for Jobs, and we don’t claim to. We also don’t claim the output is validated, so run your own pages through Google’s tools, covered below.
What Google for Jobs reads
Google’s rules live in its job posting structured data documentation. Read it once. The essentials: each job needs its own page, the markup has to match what’s visible on that page, and the required properties have to be present.
The big ones are title, description, datePosted, hiringOrganization and jobLocation. Recommended ones include validThrough, employmentType, baseSalary and directApply. The schema vocabulary itself is defined at schema.org/JobPosting.
The fields WP Career Board outputs
For each open job, the plugin writes:
- title and description from the job itself.
- datePosted from the publish date.
- validThrough from the job’s closing date, as a full date-time at the end of that day in your site’s timezone. No closing date, no
validThrough. - employmentType, mapped from your job types: full-time, part-time, contract and freelance (both as contractor), internship, temporary, volunteer and per-diem.
- hiringOrganization, from the linked company page (name, URL, logo), or the company name, or your site name if neither exists.
- identifier, using the job’s ID.
- directApply, set to true when candidates apply on your site, and false when the job points to an external apply URL.
- url and jobLocation.
- baseSalary, when a salary is entered: a currency, a single value or a min and max range, and a unit of hour, month or year.
Company pages get their own Organization markup too.
Remote jobs and salary
Remote is handled with jobLocationType set to TELECOMMUTE. If you’ve set a default country (Settings > Jobs, or derived from your site’s locale), the plugin adds it as an applicantLocationRequirements value so Google knows who can apply.
Salary needs a real number. If a job has no salary, the plugin leaves baseSalary out rather than printing an empty one. If you want to add pay transparency, fill it in on the job; it’s one of the few fields job seekers actually filter on.
Why a job gets left out
This is where owners lose time. WP Career Board deliberately outputs no JobPosting for two situations:
- The job has ended. A closed or expired job keeps its page, but the plugin stops marking it up as an open job, since Google asks you to remove expired postings.
- There’s no place to work. Google rejects a posting with no location unless it’s remote, so a job with no location and no Remote option is left out. The Jobs list flags these so you can fix them.
The Require a location setting under Settings > Jobs stops anyone posting a non-remote job without one, which prevents the second problem at the source. The Google for Jobs toggle in the same place turns the whole output on or off. It stays on alongside Yoast SEO and Rank Math, which don’t add job markup for this post type, so turn it off only if another plugin already adds it. Developers can also adjust or drop a job’s markup with the wcb_job_posting_schema filter.
Expired jobs and repeat postings
Old listings are where most job boards leak search quality. A page that still looks open after the role is filled wastes a candidate’s click, and search engines notice.
WP Career Board checks deadlines every hour. When a job’s closing date passes, it moves to an expired status and drops out of the listings, feeds, search and the sitemap. Its own URL keeps working: the page says the job has expired and points to similar jobs, so a link someone saved or shared doesn’t land on a 404. That page also tells search engines not to index it, and the open-job markup is gone.
Repeat postings are the other half. An employer who hires for the same role every quarter often creates a fresh job each time, and you end up with near-identical pages competing with each other. Reopen the old one instead. Republishing an expired or closed job gives it a new deadline and keeps the same address, so its history carries over.
The featured and expiry guide covers the settings. If your board needs something stricter, such as blocking a second posting with the same title from one employer, that’s custom work done with hooks.
What to put in the job so the markup is good
The plugin can only output what you enter, so the quality of the markup follows the quality of the job. A few habits make the difference.
Set a closing date on every job. Without one there’s no validThrough, and a posting that never expires is the kind Google tells you to avoid. Pick the job type honestly, since it feeds employmentType directly. Enter pay as a number with the right period (hourly, monthly or yearly), because “competitive” can’t be turned into a salary range.
For remote roles, tick Remote rather than typing “Remote” into the location box. The plugin treats the reserved Remote term as the remote flag, not as a place called Remote, and that’s what produces the TELECOMMUTE value. If a job is open to one country only, set your default country so that requirement is stated.
On the employer side, a company page with a logo and website gives the hiringOrganization block more to work with than a bare name.
Check your own markup
Open a published job, then test it two ways. Paste the URL into Google’s Rich Results Test, and read the structured data report in Search Console once Google has crawled the page. Fix warnings against the fields above, not against a guess.
Remember the markup is only half of it. Google also needs to crawl and index the page, and the visible job has to read like a real posting. A well-written description helps there, see our guide to writing a job description.
Getting found in AI answers and Google for Jobs
More job seekers now ask an assistant what is open near them instead of typing a search. Employers do the same when they look for boards to post on. For a niche job board, the question is whether your pages can be read, trusted and cited by ChatGPT search, Perplexity and Google’s AI features, and whether they show in Google for Jobs.
Start with what is known. Nobody outside these companies can tell you how an answer engine ranks or picks its sources, and nobody can promise a citation. What you can do is remove the reasons a page cannot be used. Everything below is ordinary, checkable practice.
Google says there is no special AI markup
Google’s page on AI features and your website states that there are no additional requirements to appear in AI Overviews or AI Mode, and no special schema.org structured data to add. A page has to be indexed and eligible to be shown in Search with a snippet. It also lists making sure your structured data matches the visible text on the page as a good practice.
So the work for Google is the same work as for Google for Jobs: a crawlable page per job, markup that agrees with the page, and no stale listings. Meeting those conditions does not guarantee crawling, indexing or serving, and we make no such promise.
Give every job a crawlable page on your domain
An assistant that browses can only cite what it can open. A job that exists only inside an embedded widget, a filtered view or a screen behind a login has no address to cite.
In WP Career Board each job is a public post with its own address under /jobs/, and the text is in the page’s HTML. That is the baseline. Check it yourself: open a job in a private window, view the page source and confirm the title, company, location and description are present without running scripts.
Keep the job’s own page free of a login wall. Applying can require an account, if you choose, but reading the job should not.
State the facts in plain text
Answer engines quote sentences. Write the role, the employer, the place or Remote, the pay and the closing date in the job itself, in normal prose or a short list, and not only inside a graphic or a collapsed section.
A candidate question such as “is this role remote and what does it pay” should be answerable from your page alone. If the salary is only in an image, or “competitive” is all you say, there is nothing to quote. The same fields that make good JobPosting markup make a good answer, so one habit serves both.
Keep the markup and the page in agreement
Google asks that structured data matches what a visitor sees. The plugin builds the markup and the page from the same job data, so they stay in step as long as you do not hide a value on the page while entering it in the data, or the other way around.
After any change to templates or a caching layer, re-test a live job in the Rich Results Test. Look for the title, the hiring organization, the location and the closing date in the detected fields, then compare each with the visible page.
Handle expired jobs so they do not mislead
A filled job that still reads as open is the fastest way to lose trust, with people and with crawlers. The plugin checks deadlines hourly. When one passes, the job leaves listings, feeds, search and the sitemap, its page says the job has ended and shows similar jobs, the page asks search engines not to index it, and the open-job markup is removed.
Your side of this is to set a closing date on every job and to close a role when it is filled. If you leave a job open with no deadline, you will keep serving a page that describes something that no longer exists.
Google’s job posting documentation asks you to remove or mark expired jobs, and it also describes an Indexing API that can be used for JobPosting pages. WP Career Board does not call that API or ping IndexNow, so on a fast-moving board you would add that separately. For most niche boards, a correct sitemap and a working expiry are enough to start.
Employer and location pages
People ask about places and companies, not only roles: which firms are hiring in a city, or what a given employer has open. Pages that answer those questions give a crawler more to work with than a single long list.
The free plugin registers a public company directory at /companies/ with a page for each employer, and public archive pages for job category, job type, location, tag and experience level, at addresses such as /job-location/. Fill the company profile properly: a description, a website and a logo. Give each location term a clear name. Thin archive pages with one job and no text add little, so look at which archives you actually want indexed.
Let the crawlers in
Check your robots.txt and any security plugin or CDN rule that blocks bots. The operators describe their crawlers in their own documents.
- OpenAI’s crawler documentation says OAI-SearchBot is what surfaces sites in ChatGPT search, and that you should allow it in robots.txt. GPTBot relates to training and is a separate choice. ChatGPT-User acts on a user’s request and does not decide whether you appear in search.
- Perplexity’s bot documentation says PerplexityBot surfaces and links sites in its results and recommends allowing it. Perplexity-User fetches a page when a person asks a question.
- Both say robots.txt changes can take up to about a day to be picked up.
Whether you allow training crawlers is a business decision. Blocking a training crawler does not by itself remove you from a search product, but read each operator’s page, since the details can change.
What about llms.txt
An llms.txt file is a proposed convention: a plain text file at the root of your site that lists your key pages for language models. We have not verified that any answer engine relies on it, and WP Career Board does not generate one. If you want to publish one, treat it as an optional extra. List your jobs archive, your company directory and your main guides, keep it short and keep it current. It is not a substitute for crawlable pages, accurate markup and good job text.
Freshness is the habit that matters
A board earns trust by being current. A few routines are enough:
- Set a closing date on every job so none stays open by accident.
- Close filled roles the same week.
- Keep your sitemap submitted in Search Console and look at its coverage report.
- Check the structured data report for errors after any theme or plugin change.
- Review the Jobs list for postings flagged as having no location.
How to check your own visibility
Do not rely on a promise from anyone, including us. Ask a few real questions of the assistants you care about, such as “software developer jobs in a city your board covers”, and see whether your pages appear. Run the same questions a few weeks apart. Look at the referral traffic in your analytics, and in Search Console check which job pages are indexed and which are not. Fix what the data shows, and ignore advice that claims a secret ranking trick.
Common mistakes on a WordPress job board
Most schema trouble isn’t the markup, it’s the job behind it. Three patterns come up again and again.
The first is stale jobs. If filled roles stay live with no deadline, Google ends up crawling pages that describe jobs that no longer exist. Closing the job in the board, rather than leaving it open, is the fix, and the plugin stops marking it up once it ends.
The second is mismatched content. Google wants the structured data to agree with what a visitor sees. Because the markup is built from the same job data as the page and the REST API, the two stay in step as long as you don’t hide the salary or location on the page while entering it in the data.
The third is duplicate markup. If you run another plugin that also prints JobPosting, you’ll have two blocks for one job. Pick one source, and switch the Google for Jobs toggle off if it isn’t this plugin.
Where this fits
The structured data is part of the free plugin, not a paid extra. For the wider picture, see the WordPress job board plugin overview, the public job board feature, and pricing for what Free and Pro each cover. Moving from another plugin? The guide to migrating from WP Job Manager covers that.