siteway

// stack · schnittstelle

Google for Jobs.

Google for Jobs ist die Stellensuche innerhalb der Google-Suche — kein eigenes Jobportal, sondern eine Box, die Google aus dem Markup der Arbeitgeber-Websites füllt. Die Eintrittskarte ist JobPosting-JSON-LD auf einer indexierbaren Detailseite je Stelle. Wie siteway das baut, steht auf dieser Seite; buchen kannst du es als Job- & Karriereportal.

stack stack: google for jobs · jobposting einsatz: detailseite je stelle prüfung: rich-results-test seit: 2006

// definition

Was ist Google for Jobs?

Google for Jobs ist eine eigene Darstellung von Stellenanzeigen in den Google-Suchergebnissen: eine Box, die bei passenden Suchanfragen über den übrigen Treffern steht und sich nach Kriterien wie Ort oder Jobtitel filtern lässt. Google selbst beschreibt sie als besondere Nutzererfahrung in der Suche — nicht als Produkt, das man bucht.

Das ist der entscheidende Unterschied zu einer Jobbörse. Es gibt kein Backend, in das man eine Anzeige einstellt, und keinen Anzeigenplatz, den man kaufen kann. Google liest die Angaben aus dem strukturierten Markup der Seiten, die es ohnehin crawlt — von Jobbörsen und von den Karriereseiten der Arbeitgeber. Wer selbst in der Stellensuche auftauchen will, braucht also keinen Vertrag, sondern eine Stellenanzeige, die Google lesen kann.

Technisch ist das ein Schema.org-Typ: JobPosting, als JSON-LD im Quelltext der Stellenseite. Es ist derselbe Mechanismus wie bei Rezepten, Produkten oder FAQ — nur mit eigenem Regelwerk. Wie wir Schema.org grundsätzlich aufbauen, steht unter Strukturierte Daten; diese Seite geht auf den Sonderfall Stellenanzeige.

// felder · pflicht & empfehlung

Die Felder des JobPosting-Markups.

fünf pflicht · viele empfohlen

Google nennt fünf Pflichtfelder. Ohne sie erkennt die Suche die Seite nicht als Stellenanzeige an: title für den Jobtitel — gemeint ist die Position, nicht die Überschrift der Anzeige. description für die vollständige Stellenbeschreibung, HTML ist darin erlaubt; sie soll Aufgaben, Qualifikation, Arbeitszeiten und Anforderungen tatsächlich abbilden und darf nicht einfach der Titel sein.

Dazu datePosted, das Datum der Veröffentlichung im Format ISO 8601, hiringOrganization für das einstellende Unternehmen — mit name, sameAs für die Unternehmenswebsite und logo — und jobLocation für den Arbeitsort. Letzteres ist ein Place mit einer PostalAddress: Straße, Ort, Region, Postleitzahl und Land. Das Land ist innerhalb der Adresse verpflichtend.

Die empfohlenen Felder sind kein Beiwerk. Google rät ausdrücklich, so viele Eigenschaften wie möglich anzugeben — je vollständiger die Angaben, desto hochwertiger ist die Anzeige für die Suchenden. Und einige davon entscheiden darüber, ob eine Anzeige überhaupt sinnvoll funktioniert: ohne validThrough hat sie kein Ablaufdatum, ohne employmentType fällt sie aus den Filtern.

Sechs empfohlene Felder setzen wir in der Praxis fast immer — weil sie Filter bedienen, Anzeigen ablaufen lassen und Doppelungen vermeiden.

// f-01laufzeit

validThrough.

Das Ablaufdatum der Anzeige, ebenfalls in ISO 8601 — mit Uhrzeit, wenn es genau sein soll. Ohne dieses Feld hat die Stelle kein Ende, und Google hat keinen Anlass, sie aus der Stellensuche zu nehmen.

zweck: anzeige läuft aus

// f-02art

employmentType.

Die Beschäftigungsart aus einer festen Werteliste: FULL_TIME, PART_TIME, CONTRACTOR, TEMPORARY, INTERN, VOLUNTEER, PER_DIEM oder OTHER. Genau danach filtern Suchende — freier Text hilft hier nicht.

zweck: filter vollzeit · teilzeit

// f-03gehalt

baseSalary.

Das Grundgehalt als MonetaryAmount mit Währung und einem QuantitativeValue darin — als fester Wert oder als Spanne über minValue und maxValue, dazu die Einheit HOUR, DAY, WEEK, MONTH oder YEAR.

zweck: gehaltsangabe · spanne

// f-04referenz

identifier.

Die eindeutige Kennung der Stelle beim Arbeitgeber, als PropertyValue mit name und value. Praktisch die Referenznummer aus dem Bewerbermanagement — sie hält Anzeige und interner Vorgang zusammen.

zweck: referenznummer

// f-05bewerbung

directApply.

Ein Wahrheitswert dafür, ob sich Suchende direkt über diese Seite bewerben können — also ohne über weitere Zwischenstationen geleitet zu werden. Wer ein eigenes Bewerbungsformular hat, sollte das auch auszeichnen.

zweck: direkte bewerbung

// f-06remote

jobLocationType.

Für Stellen, die zu 100 % remote laufen, setzt Google den Wert TELECOMMUTE vor. Dazu gehört applicantLocationRequirements mit mindestens einem Land — und ein Hinweis auf die Remote-Arbeit im sichtbaren Text.

zweck: remote sauber auszeichnen

$ cat jobposting.jsonld · beispiel für eine stellen-detailseite
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type":    "JobPosting",

  // pflicht
  "title":       "Frontend-Entwickler (m/w/d)",
  "description": "<p>Aufgaben, Qualifikation, Arbeitszeiten …</p>",
  "datePosted":  "2027-03-02",
  "hiringOrganization": { "@type": "Organization",
    "name": "…", "sameAs": "https://…", "logo": "https://…/logo.png" },
  "jobLocation": { "@type": "Place",
    "address": { "@type": "PostalAddress",
      "streetAddress": "…", "addressLocality": "Hamburg",
      "postalCode": "20…", "addressCountry": "DE" } },

  // empfohlen
  "validThrough":   "2027-05-31T23:59",
  "employmentType": "FULL_TIME",
  "identifier": { "@type": "PropertyValue",
    "name": "…", "value": "DEV-014" },
  "baseSalary": { "@type": "MonetaryAmount", "currency": "EUR",
    "value": { "@type": "QuantitativeValue",
      "minValue": 55000, "maxValue": 68000, "unitText": "YEAR" } },
  "directApply": true
}
</script>

Ein Beispiel zur Veranschaulichung — diese Seite selbst schreibt kein JobPosting aus. Markup gehört ausschließlich auf Seiten, auf denen tatsächlich eine Stelle ausgeschrieben ist.

// wie wir das umsetzen

Aus Feldern, nicht aus Fließtext.

markup folgt der anzeige

Der übliche Weg ist ein JSON-LD-Schnipsel, den jemand einmal per Hand in die Stellenseite kopiert. Beim zweiten Job ist er kopiert, beim fünften veraltet. Wir machen es wie überall im @graph-Ansatz: Die Stellenanzeige ist ein eigener Inhaltstyp im CMS mit echten Feldern — Jobtitel, Standort, Beschäftigungsart, Veröffentlichungs- und Ablaufdatum, Gehaltsband, Referenznummer. Das JobPosting wird daraus beim Ausspielen generiert. Markup und sichtbarer Text stammen aus derselben Quelle und können gar nicht auseinanderlaufen.

Jede Stelle bekommt eine eigene, indexierbare URL. Google will das Markup auf der detailliertesten Seite und ausdrücklich nicht auf einer Liste — die Übersicht bleibt bei uns also eine Übersicht, filterbar nach Standort und Abteilung, aber ohne JobPosting. Dazu gehört das Selbstverständliche, das erfahrungsgemäß am häufigsten fehlt: keine Sperre in der robots.txt, kein noindex, kein Login davor — sonst kann Googlebot die Seite nicht lesen.

Das Ablaufdatum ist bei uns ein Pflichtfeld im Redaktionsformular, nicht ein optionales Extra ganz unten. Ist eine Stelle besetzt, geht die Seite auf 410 oder das validThrough in die Vergangenheit — beides Wege, die Google für abgelaufene Anzeigen vorsieht. Geprüft wird vor dem Go-live im Rich-Results-Test, danach läuft das Monitoring über die Search Console. Für Stellen-URLs empfiehlt Google zusätzlich die Indexing API statt der Sitemap, weil sie das Crawling schneller anstößt.

Meistens liegen die Stellen schon woanders: im Bewerbermanagement. Dann holen wir sie über die Schnittstelle aus Personio oder rexx systems und rendern daraus echte Detailseiten auf deiner Domain — statt eine fertige Liste als Widget einzubetten, die oft weder eigene URLs noch lesbares Markup mitbringt. Die Personalabteilung pflegt weiter im gewohnten System, die Website liefert aus. Wie wir solche Anbindungen bauen, steht unter Schnittstellen & Integration.

  1. // schritt 01 · modellieren

    Stellenanzeige als Inhaltstyp.

    Wir legen die Felder an, die das Markup später braucht: Jobtitel, Beschreibung, Standort mit vollständiger Adresse, Beschäftigungsart, Datum, Ablaufdatum, Gehaltsband, Referenznummer. Was Google verlangt, sieht die Redaktion im Formular.

    output: feldmodell stellenanzeige

  2. // schritt 02 · generieren

    JobPosting generieren.

    Das Template baut aus denselben Feldern den sichtbaren Text und das JSON-LD. Leere Felder werden weggelassen statt mit Platzhaltern gefüllt — lieber eine Angabe weniger als eine falsche.

    output: jobposting je stelle

  3. // schritt 03 · ausliefern

    Detailseiten ausliefern.

    Je Stelle eine URL, crawlbar und indexierbar, mit Bewerbungsweg auf derselben Seite. Die Übersicht verlinkt darauf und trägt selbst kein JobPosting-Markup.

    output: indexierbare stellenseiten

  4. // schritt 04 · prüfen & pflegen ● ergebnis

    Prüfen und ablaufen lassen.

    Rich-Results-Test vor dem Go-live, danach Rich-Result-Statusbericht und URL-Prüfung in der Search Console. Besetzte Stellen verschwinden über 410 oder ein Ablaufdatum in der Vergangenheit.

    output: gültiges markup · saubere liste

// integration

JobPosting in deine Website integrieren.

drei systeme · ein muster

Der Weg ist in jedem System derselbe, nur die Vokabeln wechseln. Eine Stellenanzeige braucht einen eigenen Inhaltstyp mit definierten Feldern — Jobtitel, Beschreibung, Standort, Veröffentlichungs- und Ablaufdatum, Beschäftigungsart, Kennung und, wenn es eines gibt, das Gehaltsband. Sie braucht eine eigene indexierbare URL je Stelle. Und aus genau diesen Feldern erzeugt das Template beim Rendern das JobPosting-JSON-LD. So können sichtbarer Text und Markup gar nicht auseinanderlaufen — genau das ist die Anforderung, die Google stellt. Stellenanzeigen bei Google einbinden heißt also nicht, irgendwo eine Anzeige zu schalten, sondern die eigenen Felder sauber auszuspielen.

Dazu gehört, dass das Ablaufdatum nicht nur erfasst, sondern auch ausgewertet wird: Es gehört ins validThrough, und ist es überschritten, muss die Anzeige aus der Stellensuche verschwinden. Feldmodell, URL-Struktur und Ausgabe des Markups bauen wir mit den Bordmitteln des jeweiligen Systems selbst — zugeschnitten auf das, was die Stellen wirklich brauchen: zusätzliche Felder, Mehrsprachigkeit, Daten aus dem Bewerbermanagement. Die Auszeichnung ist damit Teil der Umsetzung, nicht ein nachträglicher Aufsatz. So sieht das in den drei Systemen aus, mit denen wir arbeiten.

In allen drei Systemen gilt dasselbe Prinzip: Markup und sichtbarer Text werden aus derselben Quelle gerendert, deshalb können sie gar nicht auseinanderlaufen — genau das verlangt Google. In den strukturierten Daten steht damit exakt das, was zur Stelle gepflegt wurde: Bleibt ein Feld leer, bleibt es auch im Markup leer, und der Rich-Results-Test zeigt es. Am häufigsten trifft es das Ablaufdatum. Deshalb steht validThrough bei uns als Pflichtfeld im Redaktionsformular — in TYPO3, in WordPress und in Statamic gleichermaßen — und wird beim Rendern auch ausgewertet: Ist es überschritten, fällt die Stelle aus der Ausspielung.

// fehlerquellen · 6 klassiker

Woran es in der Praxis scheitert.

meistens nicht am text

Wenn Stellen nicht in der Stellensuche auftauchen, liegt es selten an der Formulierung der Anzeige. Das sind die sechs Ursachen, die uns in Audits am häufigsten begegnen — und was Google jeweils dazu sagt.

// x-01laufzeit

Kein Ablaufdatum.

validThrough ist optional — und wird deshalb gern weggelassen. Die Folge: Die Anzeige hat kein Ende. Sie steht weiter in der Stellensuche, während die Stelle längst besetzt ist.

lösung: ablaufdatum pflegen

// x-02deckung

Markup ohne sichtbare Entsprechung.

Gehalt, Beschäftigungsart oder Standort stehen nur im JSON-LD, nicht im sichtbaren Text. Google verlangt, dass alle Angaben aus dem Markup auf der gerenderten Seite zu sehen sind.

lösung: eine quelle für beides

// x-03altlast

Besetzte Stellen bleiben online.

Google nennt drei Wege, eine Stelle zu entfernen: validThrough in die Vergangenheit setzen, die Seite auf 404 oder 410 laufen lassen, oder das Markup entfernen. Wer keinen davon geht, sammelt Bewerbungen auf Positionen, die es nicht mehr gibt.

lösung: 410 oder validThrough

// x-04ebene

Liste statt Detailseite ausgezeichnet.

Das Markup landet auf der Stellenübersicht, weil dort alle Jobs stehen. Google verlangt es auf der detailliertesten Seite und rät ausdrücklich davon ab, Listenseiten auszuzeichnen.

lösung: markup auf die detailseite

// x-05erreichbarkeit

Keine indexierbare URL.

Die Stellen kommen aus einem eingebetteten Widget, liegen hinter einem Login oder sind über robots.txt und noindex gesperrt. Was Googlebot nicht crawlen und indexieren kann, kann auch nicht in der Stellensuche stehen.

lösung: eigene seite je stelle

// x-06inhalt

Anzeigentitel statt Jobtitel.

In title steht „Wir suchen dich!" statt der Position, und description enthält drei Zeilen statt der vollständigen Stellenbeschreibung. Google will im Titel den Jobtitel und in der Beschreibung Aufgaben, Qualifikation und Anforderungen.

lösung: position benennen · volltext

// faq

Häufige Fragen.

Was ist Google for Jobs?

Google for Jobs ist die Stellensuche innerhalb der Google-Suche: eine Box mit Stellenanzeigen, die bei passenden Suchanfragen über den übrigen Treffern steht und sich nach Kriterien wie Ort oder Jobtitel filtern lässt. Es ist kein eigenes Jobportal, in das man eine Anzeige einstellt, und es gibt darin keinen buchbaren Anzeigenplatz. Google zieht die Angaben aus dem strukturierten Markup der Seiten, die es ohnehin crawlt — also aus der Karriereseite des Arbeitgebers. Sichtbarkeit entsteht dadurch, dass eine Stelle eine crawlbare Detailseite mit korrektem JobPosting-Markup hat.

Welche Felder braucht das JobPosting-Markup?

Google nennt fünf Pflichtfelder: title für den Jobtitel, description für die vollständige Stellenbeschreibung (HTML ist darin erlaubt), datePosted für das Veröffentlichungsdatum, hiringOrganization für das einstellende Unternehmen und jobLocation für den Arbeitsort. Empfohlen sind unter anderem validThrough, employmentType, baseSalary, identifier und directApply sowie jobLocationType mit dem Wert TELECOMMUTE zusammen mit applicantLocationRequirements für Stellen, die vollständig remote laufen. Google rät ausdrücklich dazu, so viele Eigenschaften wie möglich anzugeben — je vollständiger die Angaben, desto hochwertiger ist die Anzeige für die Suchenden.

Muss jede Stelle eine eigene Seite haben?

Ja. Google verlangt das Markup auf der detailliertesten Seite — also auf der Detailseite einer einzelnen Stelle und ausdrücklich nicht auf einer Übersicht, die eine Liste von Stellen zeigt. Die Seite muss crawlbar und indexierbar sein: nicht durch die robots.txt gesperrt, nicht auf noindex gesetzt und nicht hinter einem Login. Und das Markup muss auf derselben Seite stehen wie die Stellenbeschreibung, die Bewerberinnen und Bewerber lesen. siteway baut deshalb je Stelle eine eigene URL, während die Übersichtsseite eine reine Liste ohne JobPosting-Markup bleibt.

Was passiert mit abgelaufenen Stellenanzeigen?

Die müssen raus. Google nennt drei Wege: das Feld validThrough auf ein Datum in der Vergangenheit setzen, die Seite entfernen, sodass sie den Statuscode 404 oder 410 liefert, oder das JobPosting-Markup von der Seite nehmen. Bleibt eine besetzte Stelle unverändert online, taucht sie weiter in der Stellensuche auf — und es kommen Bewerbungen auf eine Position, die es nicht mehr gibt. Bei siteway ist das Ablaufdatum deshalb ein Pflichtfeld im Redaktionsformular und kein Nachgedanke.

Reicht es, die Stellen aus Personio oder rexx systems einzubetten?

Für die Stellensuche meist nicht. Eine eingebettete Liste liefert oft keine eigene indexierbare URL je Stelle und kein Markup, das Google auf der Seite findet. Deshalb holt siteway die Stellen über die Schnittstelle aus dem HR-System und rendert daraus echte Detailseiten auf deiner eigenen Domain — mit JobPosting-Markup aus denselben Feldern. Gepflegt wird weiter dort, wo die Personalabteilung ohnehin arbeitet, ausgeliefert wird über deine Website.

Wie kommt das JobPosting-Markup in WordPress oder TYPO3?

Über den Inhaltstyp des jeweiligen Systems — und über die Ausgabe, die wir dafür bauen. In WordPress entsteht die Stellenanzeige als Custom Post Type mit eigenen Meta-Feldern in einem Plugin, das wir für das Projekt schreiben; jede Stelle bekommt über eine eigene Permalink-Struktur ihre URL, und das JSON-LD wird über einen Hook in den Seitenkopf geschrieben — aus denselben Feldern, die auch die sichtbare Seite füllen. In TYPO3 liegen die Stellen als Records einer eigenen Extension mit definierten Feldern, das Site Handling gibt jeder Stelle eine eigene indexierbare URL, und das Markup rendert das Fluid-Template der Detailansicht oder es wird per TypoScript ausgegeben. In Statamic ist es eine Collection mit Blueprint als Feldmodell, jede Stelle ein Entry mit eigener URL, und das JSON-LD entsteht im Antlers- oder Blade-Layout aus denselben Werten. Entscheidend ist in allen drei Fällen dasselbe: Weil Markup und sichtbarer Text aus derselben Quelle kommen, können sie nicht auseinanderlaufen — und das Ablaufdatum muss nicht nur erfasst, sondern auch ausgewertet werden.

Wie prüft ihr, ob das Markup funktioniert?

Vor dem Go-live läuft jede Stellenseite gegen Googles Rich-Results-Test. Danach beobachten wir den Rich-Result-Statusbericht in der Search Console und prüfen einzelne Seiten mit der URL-Prüfung. Für Stellen-URLs empfiehlt Google zusätzlich die Indexing API statt der Sitemap, weil sie Googlebot schneller zum Crawlen anstößt; eine Sitemap für die Abdeckung der gesamten Website bleibt trotzdem sinnvoll. So fällt ein fehlendes Pflichtfeld sofort auf — und nicht erst daran, dass keine Bewerbungen kommen.

Baut siteway das für unsere Karriereseite?

Ja. Diese Seite beschreibt die Technik: wie das JobPosting-Markup aus den Feldern der Stellenanzeige entsteht, welche Angaben hineingehören und wie Detailseite, Ablaufdatum und Prüfung zusammenspielen. Gebucht wird das als Komponente Job- & Karriereportal — mit Stellenanzeigen im CMS, filterbarer Übersicht, Bewerbungsformular und Anbindung ans Bewerbermanagement.

// Stellen sichtbar in der Google-Suche?

Projekt anfragen