Zum Inhalt springen
    WingoUI
    KomponentenVorlagenDokuPreiseKI-AgentenBlogChangelogKontakt
    1. Startseite
    2. Blog
    3. Praxis: Screens und Apps
    4. Karriereseite Template in React: Bewerbung und JobPosting
    Read in English
    1. Blog
    2. Praxis: Screens und Apps
    3. Karriereseite Template in React: Bewerbung und JobPosting
    Praxis: Screens und Apps
    Praxis: Screens und Apps

    Karriereseite Template in React: Bewerbung und JobPosting

    SR
    Serban Rusu · Gründer von Wingo UI
    6. Nov. 2026 · 12 Min. Lesezeit

    Auf dieser Seite

    0%
    1. Was gehört in ein Karriereseite Template?
    2. Wie installierst du das Karriereseite Template?
    3. Wie ersetzt du die Beispielinhalte?
    4. Warum braucht jede Stelle eine eigene Seite?
    5. Wie ergänzt du JobPosting Structured Data für die Jobsuche von Google?
    6. Wohin sollen die Bewerbungen gehen?
    7. Wie verhält sich die Karriereseite auf dem Smartphone?
    8. Gehört das Team auf die Karriereseite oder auf die About-Seite?
    9. Welche Fehler passieren auf Karriereseiten am häufigsten?
    10. Nächster Schritt
    11. Häufige Fragen
      1. Was gehört auf eine Karriereseite?
      2. Kann ich JobPosting Structured Data auf die Seite mit der Stellenliste setzen?
      3. Wie kennzeichne ich eine Remote-Stelle für Google for Jobs?
      4. Was passiert mit einer Stellenanzeige, wenn die Stelle besetzt ist?
      5. Ist das Karriereseite Template von Wingo UI kostenlos?

    Kurz gesagt

    Ein Karriereseite Template, das Bewerbungen bringt, braucht eine kurze Mission, echte Menschen, Benefits, die Schritte im Bewerbungsprozess, eine filterbare Liste der Stellen mit Gehaltsspannen und für jede Stelle eine eigene Seite mit einem Bewerbungsformular, das in deinem Postfach oder deinem ATS ankommt. Setz JobPosting Structured Data auf jede Stellenseite, nie auf die Liste, und liefere einen 404, sobald eine Stelle besetzt ist. Die Templates Careers Page und Job Detail Page von Wingo UI rendern die Oberfläche; die Stellen, die Texte und den Handler für die Bewerbungen lieferst du.

    Veröffentlicht am 6. Nov. 2026

    Eine Karriereseite hat genau eine Aufgabe: aus einem neugierigen Besucher eine Bewerbung zu machen, auf die du antworten kannst. Die meisten Karriereseite Templates hören bei der Optik auf. Sie liefern einen Hero, ein Raster mit Werten und eine Liste der Stellen und lassen genau die Teile weg, die entscheiden, ob sich überhaupt jemand bewirbt und ob Google deine Stellen listet. Dieser Guide zeigt ein Karriereseite Template in React und Next.js, das die ganze Arbeit erledigt: Mission, Team, Benefits, filterbare Stellen, ein Job-Drawer, ein Bewerbungsformular, eine Seite pro Stelle und JobPosting Structured Data. Die Oberfläche ist unser Template Careers Page, wir sind also nicht neutral. Datenmodell, Routen und Markup funktionieren aber mit jeder Vorlage für Stellenseiten.

    Was gehört in ein Karriereseite Template?

    Ein Karriereseite Template sollte der Reihe nach die Fragen beantworten, die sich jemand vor der Bewerbung stellt: Warum gibt es die Firma, mit wem würde ich arbeiten, wie arbeitet man dort und was bekomme ich, wie läuft die Bewerbung ab, welche Stellen sind zu welchem Gehalt offen und was mache ich, wenn keine passt. Als wir am 6. November 2026 nach „careers page template“ gesucht haben, bestanden die Ergebnisse vor allem aus No-Code- und Page-Builder-Vorlagen (involve.me, WeWeb, Notion, die Careers-Liste von Webflow, ein Job-Board-Theme für Framer), einem Arbeitsblatt zum Ausdrucken und den Baukästen für Karriereseiten in Bewerbermanagementsystemen (ATS) wie Workable. Varianten wie „careers page template react“, „careers page design template“ oder „careers page example“ bringen mehr Seiten derselben Art. Wer eine Karriereseite gestalten will, findet dort gute Layouts. Fast keine davon sagt aber, wohin die Bewerbung geht oder wie eine Stelle in den Jobergebnissen von Google auftaucht.

    Hier steht, wofür jeder Abschnitt da ist und welches Prop ihn in CareersPage steuert:

    AbschnittDie Frage, die er beantwortetIm Template
    HeroWarum gibt es diese Firma, in einem Absatz?labels.heroTitle, labels.heroDescription
    ZahlenWie groß und wie alt ist sie?stats, showStats
    TeamMit wem würde ich arbeiten?team, moments, showTeam
    Werte und BenefitsWie arbeiten die Leute hier, und was bekomme ich?values, perks
    BewerbungsprozessWas passiert nach der Bewerbung, und wie lange dauert es?steps, showProcess
    Offene StellenGibt es eine Stelle für mich, wo und für wie viel?roles, departments, groupByDepartment
    InitiativbewerbungWas, wenn keine Stelle passt?showCta, labels.ctaPrimary

    Zwei davon wiegen schwerer, als es aussieht. Gruppier die Stellen nach Team: Der UX-Guide von Workable für Karriereseiten (opens in a new tab) (aktualisiert im September 2023) empfiehlt das, und genau das macht groupByDepartment, solange der Chip All ausgewählt ist. Und zeig die Gehaltsspanne, denn in mehreren US-Bundesstaaten schreibt das Gesetz sie vor: Die Liste der Bundesstaaten von Paycor (opens in a new tab) (aktualisiert am 20. November 2025) nennt Kalifornien, Colorado, Illinois, New York und Washington als Staaten, die Gehaltsangaben in Stellenanzeigen verlangen. In Colorado gilt das für jeden Arbeitgeber; die anderen vier setzen eine Mindestgröße voraus (4 Beschäftigte in New York, 15 in den übrigen). Prüf die Regeln für jeden Bundesstaat, in dem du einstellst.

    Wie installierst du das Karriereseite Template?

    Ein Befehl kopiert beide Templates und alles, was sie importieren. Es sind Pro-Items, das Konto hinter der CLI braucht also Wingo UI Pro.

    bash
    npx wingo-ui@latest add careers-page job-detail-page

    Du bekommst components/templates/careers-page.tsx und careers-page-data.ts, job-detail-page.tsx und job-detail-page-data.ts sowie ihre Teile: den kostenlosen Drawer für das Panel mit der Stelle, den kostenlosen Search Input für den Stellenfilter, den kostenlosen Empty State für „No roles match those filters“, den File Upload für den Lebenslauf und die Team Section. Ohne Props rendert die Seite neun Beispielstellen einer ausgedachten Firma namens Acme.

    Tipp „design“ ins Suchfeld, wähl einen Abteilungs-Chip und klick dann auf eine Stelle: Sie öffnet sich in einem Seitenpanel mit dem Bewerbungsformular. Auf dem Smartphone ist das Panel ein Bottom Sheet, das du zum Schließen nach unten ziehst
    $ npx wingo-ui@latest add careers-page
    ProDoku: Careers Page

    Die Liste kann drei Dinge, die eine statische Liste nicht kann. Suche, Abteilungs-Chips und ein Standort-Select grenzen die Stellen schon beim Tippen ein, und jeder Chip zeigt, wie viele Stellen er trifft. Ein Klick auf eine Stelle öffnet einen Drawer mit Beschreibung, Anforderungen, deinen Benefits und dem Formular, so kann jemand drei Stellen lesen, ohne den Filter zu verlieren. Und jede Zeile bleibt ein echter Link auf /careers/<slug>: Cmd- oder Strg-Klick öffnet die Seite, und Crawler folgen dem Link.

    Wie ersetzt du die Beispielinhalte?

    Leg deine Stellen in einer typisierten Datei ab, aus der die Liste, die Stellenseiten und die strukturierten Daten lesen. Der Typ JobDetail der Stellenseite enthält schon alles, was die Karriereliste braucht, ein einziges Array speist also beide Templates. Ergänz die zwei Angaben, die strukturierte Daten brauchen und eine Zeile in der Liste nicht: wo Bewerber bei Remote-Stellen wohnen dürfen und für alle anderen Stellen die Büroadresse.

    ts
    // app/careers/jobs.ts
    import type { JobDetail } from "@/components/templates/job-detail-page-data"
    type Office = { locality: string; region?: string; country: string }
    export type Job = JobDetail & {
    postedAt: string
    // weglassen, wenn die Stelle offen bleibt, bis sie besetzt ist
    validThrough?: string
    } & (
    | { workplace: "Remote"; eligibleCountries: string[] }
    | { workplace: "Hybrid" | "On-site"; office: Office }
    )
    export const JOBS: Job[] = [
    {
    slug: "senior-frontend-engineer",
    title: "Senior Frontend Engineer",
    department: "Engineering",
    location: "Remote, USA",
    workplace: "Remote",
    eligibleCountries: ["US"],
    type: "Full-time",
    salaryMin: 160000,
    salaryMax: 190000,
    postedAt: "2026-11-02",
    isNew: true,
    summary: "Du verantwortest den Editor, den unsere Kunden jeden Morgen öffnen.",
    about: ["Du kommst in ein Team aus vier Engineers und einem Designer."],
    responsibilities: ["Den Editor mit React und TypeScript bauen"],
    requirements: ["5+ Jahre Erfahrung mit Web-Apps, davon 3+ mit React"],
    },
    ]

    Dann renderst du die Liste aus einem kleinen Client-Wrapper, weil onApply eine Funktion ist und der Router-Link eine Client-Komponente:

    tsx
    // app/careers/careers-view.tsx
    "use client"
    import Link from "next/link"
    import { CareersPage } from "@/components/templates/careers-page"
    import { JOBS } from "./jobs"
    import { MOMENTS, PERKS, STEPS, TEAM, VALUES } from "./content"
    import { sendApplication } from "./send-application"
    export function CareersView() {
    return (
    <CareersPage
    roles={JOBS}
    departments={["Engineering", "Design", "Customer success"]}
    values={VALUES}
    perks={PERKS}
    team={TEAM}
    moments={MOMENTS}
    steps={STEPS}
    showStats={false}
    labels={{
    heroEyebrow: "Karriere bei Acme",
    heroDescription: "Wir sind sechs Leute und bauen ein Planungstool für kleine Teams, aus Brooklyn und drei US-Zeitzonen.",
    processTitle: "Drei Schritte, etwa zwei Wochen",
    ctaEmail: "jobs@acme.com",
    }}
    linkComponent={Link}
    // Header und Footer rendert schon das Layout der Site
    header={false}
    footer={false}
    onApply={sendApplication}
    />
    )
    }

    content.ts enthält deine Werte, Perks, das Team, die Momente und die Schritte, typisiert mit CareersValue, CareersPerk, CareersTeamMember, CareersMoment und CareersStep aus careers-page-data.ts. Geh auch die Standard-Labels durch. Der Beispieltext verspricht Dinge wie „We reply to every application within five working days“ und eine bezahlte Probeaufgabe. Das sind gute Versprechen, wenn du sie hältst, und ein schlechter erster Eindruck, wenn nicht. Die Beispielzahlen (42 Teammitglieder, 11 Länder) sind der Grund für showStats={false} im Beispiel: Schalte die Zahlen wieder ein, wenn du welche hast, auf die du stolz bist.

    Warum braucht jede Stelle eine eigene Seite?

    Der Drawer ist eine Abkürzung für Menschen. Die Seite ist für alles andere da: für den Link, den eine Recruiterin in eine Nachricht kopiert, für die URL, die dein ATS per E-Mail verschickt, und als einziger Ort, an dem Google Job-Markup akzeptiert. Googles Leitfaden zu strukturierten Daten für Stellenanzeigen (opens in a new tab) (geprüft am 6. November 2026) legt fest, dass JobPosting nur auf Seiten mit genau einer Stellenanzeige stehen darf und nicht auf Seiten, die Stellen auflisten. Die Karriereliste trägt also kein JobPosting, und jede Seite unter /careers/<slug> trägt genau eins.

    tsx
    // app/careers/[slug]/page.tsx
    import type { Metadata } from "next"
    import { notFound } from "next/navigation"
    import { JOBS } from "../jobs"
    import { jobPostingJsonLd } from "../job-posting"
    import { JobView } from "./job-view"
    type Props = { params: Promise<{ slug: string }> }
    // ein Slug, der nicht in JOBS steht, ist ein 404, so fällt eine entfernte Stelle aus Google heraus.
    // mit aktiviertem cacheComponents entfällt diese Option in Next.js 16, dann erledigt das notFound() unten die Arbeit
    export const dynamicParams = false
    export function generateStaticParams() {
    return JOBS.map((job) => ({ slug: job.slug }))
    }
    export async function generateMetadata({ params }: Props): Promise<Metadata> {
    const { slug } = await params
    const job = JOBS.find((item) => item.slug === slug)
    if (!job) return {}
    return {
    title: `${job.title} (${job.location})`,
    description: job.summary,
    alternates: { canonical: `/careers/${job.slug}` },
    }
    }
    export default async function JobRoute({ params }: Props) {
    const { slug } = await params
    const job = JOBS.find((item) => item.slug === slug)
    if (!job) notFound()
    const similar = JOBS.filter((item) => item.department === job.department && item.slug !== job.slug)
    const jsonLd = jobPostingJsonLd(job, `https://acme.com/careers/${job.slug}`)
    return (
    <>
    <script
    type="application/ld+json"
    dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd).replace(/</g, "\\u003c") }}
    />
    <JobView job={job} similar={similar} />
    </>
    )
    }
    tsx
    // app/careers/[slug]/job-view.tsx
    "use client"
    import Link from "next/link"
    import { JobDetailPage } from "@/components/templates/job-detail-page"
    import type { JobDetail, JobRole } from "@/components/templates/job-detail-page-data"
    import { sendApplication } from "../send-application"
    export function JobView({ job, similar }: { job: JobDetail; similar: JobRole[] }) {
    return (
    <JobDetailPage
    role={job}
    similarRoles={similar}
    linkComponent={Link}
    header={false}
    footer={false}
    onApply={sendApplication}
    />
    )
    }

    In Next.js 16 ist params ein Promise, deshalb warten beide Funktionen darauf. Das JSON-LD-Script steht in der Server-Seite und damit schon in der ersten HTML-Antwort, auch für Crawler, die nie JavaScript ausführen. Unser Guide zu JSON-LD in Next.js erklärt, warum < maskiert wird und wie du das Markup mit der Seite synchron hältst.

    Scroll durch die Stelle: Auf dem Desktop bleibt die Bewerbungskarte neben der Beschreibung stehen. Unter 1024px erscheint unten eine Leiste mit Apply now; tipp darauf und sende das leere Formular ab, dann bekommt das erste fehlende Feld den Fokus
    $ npx wingo-ui@latest add job-detail-page
    ProDoku: Job Detail Page

    Wie ergänzt du JobPosting Structured Data für die Jobsuche von Google?

    Google verlangt fünf Properties: title, description (die volle Beschreibung als HTML), datePosted, hiringOrganization und jobLocation. Bei einer Stelle, die komplett remote ist, darf applicantLocationRequirements an die Stelle von jobLocation treten. Lohnend sind außerdem validThrough, employmentType, baseSalary, identifier, directApply und für Remote-Stellen jobLocationType zusammen mit applicantLocationRequirements. Bau alles aus demselben Job, den die Seite rendert, dann behauptet das Markup nie etwas, das der Leser nicht sieht:

    ts
    // app/careers/job-posting.ts
    import type { Job } from "./jobs"
    const EMPLOYMENT = { "Full-time": "FULL_TIME", "Part-time": "PART_TIME", Contract: "CONTRACTOR" } as const
    const escapeHtml = (text: string) =>
    text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
    const list = (items: string[]) => `<ul>${items.map((item) => `<li>${escapeHtml(item)}</li>`).join("")}</ul>`
    export function jobPostingJsonLd(job: Job, url: string) {
    // derselbe Text, den die Seite zeigt, als html
    const description = [
    ...job.about.map((paragraph) => `<p>${escapeHtml(paragraph)}</p>`),
    `<h3>What you'll do</h3>${list(job.responsibilities)}`,
    `<h3>What you'll bring</h3>${list(job.requirements)}`,
    ].join("")
    return {
    "@context": "https://schema.org",
    "@type": "JobPosting",
    title: job.title,
    description,
    datePosted: job.postedAt,
    validThrough: job.validThrough,
    employmentType: EMPLOYMENT[job.type],
    url,
    directApply: true,
    identifier: { "@type": "PropertyValue", name: "Acme", value: job.slug },
    hiringOrganization: {
    "@type": "Organization",
    name: "Acme",
    sameAs: "https://acme.com",
    logo: "https://acme.com/logo.png",
    },
    ...(job.workplace === "Remote"
    ? {
    jobLocationType: "TELECOMMUTE",
    applicantLocationRequirements: job.eligibleCountries.map((name) => ({ "@type": "Country", name })),
    }
    : {
    jobLocation: {
    "@type": "Place",
    address: {
    "@type": "PostalAddress",
    addressLocality: job.office.locality,
    addressRegion: job.office.region,
    addressCountry: job.office.country,
    },
    },
    }),
    ...(job.salaryMin && job.salaryMax
    ? {
    baseSalary: {
    "@type": "MonetaryAmount",
    currency: job.salaryCurrency ?? "USD",
    value: { "@type": "QuantitativeValue", minValue: job.salaryMin, maxValue: job.salaryMax, unitText: "YEAR" },
    },
    }
    : {}),
    }
    }

    Ein paar Regeln aus demselben Leitfaden entscheiden, ob das funktioniert:

    • TELECOMMUTE ist nur für Stellen gedacht, die zu 100% remote sind, und die Beschreibung muss das klar sagen. Dieser Satz gehört also in about. Eine hybride Stelle mit zwei Bürotagen behält ihre Büroadresse in jobLocation; deshalb macht der Typ Job das Feld office für alles Pflicht, was nicht Remote ist.
    • Eine Remote-Stelle braucht über applicantLocationRequirements mindestens ein Land, in dem Bewerber wohnen dürfen.
    • baseSalary ist die tatsächliche Spanne des Arbeitgebers, mit unitText als HOUR, DAY, WEEK, MONTH oder YEAR (Groß- und Kleinschreibung zählt).
    • Ist eine Stelle besetzt, nimm sie offline: ein 404 oder 410, kein Markup mehr oder ein validThrough in der Vergangenheit. Wenn du sie aus JOBS löschst, hast du die erste Variante, denn die Route kennt nur die Slugs in JOBS und ruft für alle anderen notFound() auf. Google warnt, dass veraltete Stellen eine manuelle Maßnahme nach sich ziehen können.

    Google nennt die Länder, in denen die Jobsuche (Google for Jobs) Ergebnisse zeigt; dazu gehören ganz Nordamerika und Lateinamerika sowie in Europa unter anderem Großbritannien, Deutschland und Frankreich. Teste eine live geschaltete Stellenseite mit dem Test für Rich-Suchergebnisse (opens in a new tab), bevor du dich darauf verlässt.

    Wohin sollen die Bewerbungen gehen?

    Bewerbungen landen dort, wohin dein onApply-Handler sie schickt: bei einem Route Handler auf deinem eigenen Server, der sie speichert oder an dein ATS weiterleitet. Ohne onApply warten beide Templates 900 ms und zeigen dann die Bestätigung. In einer Demo ist das richtig, auf einer Live-Site ist es ein stiller Fehler, also schließ den Handler vor dem Launch an. Der Helper unten funktioniert für beide Templates, weil ihre Bewerbungsobjekte diese Felder gemeinsam haben. Die Stellenseite schickt zusätzlich consent mit, die Antwort auf ihre Checkbox, ob Acme die Bewerbung 12 Monate aufbewahren darf. Speicher sie zusammen mit der Bewerbung:

    ts
    // app/careers/send-application.ts
    type Application = {
    role?: { slug: string }
    name: string
    email: string
    linkedin: string
    note: string
    resume?: File
    // schickt nur die Stellenseite
    consent?: boolean
    }
    // bei einem Reject zeigt das Formular seine "failed"-Meldung
    export async function sendApplication(application: Application) {
    const body = new FormData()
    body.set("role", application.role?.slug ?? "open")
    body.set("name", application.name)
    body.set("email", application.email)
    body.set("linkedin", application.linkedin)
    body.set("note", application.note)
    if (application.consent !== undefined) body.set("consent", String(application.consent))
    if (application.resume) body.set("resume", application.resume)
    const response = await fetch("/api/applications", { method: "POST", body })
    if (!response.ok) throw new Error(`Bewerbung fehlgeschlagen: ${response.status}`)
    }

    Schick die Bewerbung an einen Route Handler, nicht an eine Server Action. Das Feld für den Lebenslauf nimmt PDF- und Word-Dateien bis 10 MB an, und laut der Doku von Next.js 16 sind Anfragen an Server Actions auf 1 MB begrenzt, solange du serverActions.bodySizeLimit nicht hochsetzt. Prüf auch, wie groß Anfragen bei deinem Hoster sein dürfen.

    ts
    // app/api/applications/route.ts
    const MAX_RESUME = 10 * 1024 * 1024
    const RESUME_TYPES = [
    "application/pdf",
    "application/msword",
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    ]
    export async function POST(request: Request) {
    const form = await request.formData()
    const name = String(form.get("name") ?? "").trim()
    const email = String(form.get("email") ?? "").trim()
    const resume = form.get("resume")
    if (!name || !/^\S+@\S+\.\S+$/.test(email)) {
    return Response.json({ error: "Name und eine gültige E-Mail-Adresse sind Pflicht" }, { status: 400 })
    }
    if (resume instanceof File && (resume.size > MAX_RESUME || !RESUME_TYPES.includes(resume.type))) {
    return Response.json({ error: "Der Lebenslauf muss eine PDF- oder Word-Datei bis 10 MB sein" }, { status: 400 })
    }
    // speichern oder an dein ATS weiterleiten, mit dem geheimen Schlüssel, der nie im Browser landet
    return Response.json({ ok: true }, { status: 201 })
    }

    Wenn du schon ein ATS nutzt, lass es die Quelle der Wahrheit bleiben. Greenhouse ist ein gutes Beispiel: Die Job Board API (opens in a new tab) (geprüft am 6. November 2026) liefert deine Stellen öffentlich und ohne Authentifizierung aus, und content=true ergänzt die volle Beschreibung, die Abteilung und das Büro. JOBS kann also ein Fetch zur Build-Zeit sein. Der Endpunkt für Bewerbungen braucht deinen Job Board API Key per Basic Auth, und die Doku rät, Formular-Posts über deinen eigenen Server zu leiten. Genau das meint der Kommentar im Handler oben. Der Guide zum Kontaktformular in Next.js behandelt Spamschutz und E-Mail-Versand für dieselbe Art von Handler.

    Wie verhält sich die Karriereseite auf dem Smartphone?

    Auf dem Smartphone ändern die Templates ihre Form, statt nur zu schrumpfen. Unter 640px scrollen die Abteilungs-Chips in einer Reihe seitwärts. Unter 768px öffnet das Standort-Select ein Bottom Sheet. Der Job-Drawer wird zum Bottom Sheet, das du zum Schließen nach unten ziehst, und im Feld für den Lebenslauf reicht ein Tipp, um eine Datei zu wählen. Auf der Stellenseite wird die mitlaufende Bewerbungskarte unter 1024px zu einer Leiste am unteren Rand, oberhalb der Safe Area, und zwar nur, solange das Formular nicht zu sehen ist.

    Auch die Tastatur funktioniert: / fokussiert das Suchfeld, Enter auf einer Stelle öffnet den Drawer, Escape schließt ihn, und auf der Stellenseite springt der Fokus nach einem fehlgeschlagenen Absenden auf das erste Feld mit einem Problem. Die Zeilen mit den Stellen sind echte Links, Screenreader kündigen sie also als Links an, und ein Mittelklick öffnet einen neuen Tab.

    Gehört das Team auf die Karriereseite oder auf die About-Seite?

    Auf beide, mit unterschiedlichen Aufgaben. Auf der Karriereseite beantwortet das Team die Frage „Mit wem würde ich arbeiten?“, und das Design bold ersetzt das Foto-Mosaik durch die Team Section mit ihrer Kachel „We're hiring“. Auf deiner About-Seite verlinkt derselbe Block zurück auf die Karriereseite und zählt die offenen Stellen:

    tsx
    // app/about/team.tsx
    import { TeamSection } from "@/components/blocks/team-section"
    import { JOBS } from "@/app/careers/jobs"
    export function AboutTeam() {
    return (
    <TeamSection
    title="Die Leute hinter Acme"
    description="Sechs Leute in Brooklyn und verteilt über drei US-Zeitzonen."
    members={[{ name: "Emma Carter", role: "Gründerin" }]}
    layout="cards"
    columns={3}
    openRoles={JOBS.length}
    hiring={JOBS.length > 0}
    hiringHref="/careers"
    />
    )
    }
    Das Layout cards mit drei offenen Stellen: Die letzte Kachel verlinkt auf die Karriereseite und zählt sie. Auf dem Smartphone stapeln sich die Karten in einer Spalte
    $ npx wingo-ui@latest add team-section
    ProDoku: Team Section

    Setz hiring={false}, wenn keine Stelle offen ist, damit die Kachel niemanden zu einer leeren Liste einlädt. Unser Guide zum SaaS Website Template zeigt, wie sich die Karriereseite in die übrigen Seiten einer Firmen-Website einfügt, und in der Kategorie Praxis: Screens und Apps findest du weitere Screens, die genauso gebaut sind.

    Welche Fehler passieren auf Karriereseiten am häufigsten?

    • Beispieltext stehen gelassen. Die 40.000 Teams von Acme und das Versprechen, innerhalb von fünf Tagen zu antworten, gehören nicht dir. Durchsuch die Labels vor dem Launch nach „Acme“.
    • Keine Gehaltsspannen. Mehrere US-Bundesstaaten verlangen sie in Stellenanzeigen, und eine Spanne in der Liste erspart beiden Seiten eine Gesprächsrunde, wenn das Gehalt nicht passt.
    • Abgelaufene Stellen noch online. Ein Array, ein 404, sobald eine Stelle daraus verschwindet.
    • JobPosting auf der Listenseite. Google akzeptiert es dort nicht; ein Posting pro Stellenseite.
    • Ein Bewerbungsformular, das ins Leere führt. Teste onApply mit einer echten Datei und lass die Funktion bei einem Fehler rejecten, damit das Formular den Fehler auch anzeigt.

    Nächster Schritt

    Klick dich durch die Careers Page und die Job Detail Page in allen ihren Designs, installier sie dann mit npx wingo-ui@latest add careers-page job-detail-page und ersetz die Beispielstellen durch deine eigenen. Beide Templates und die Team Section gehören zu Wingo UI Pro: $8 im Monat, $80 im Jahr oder einmalig $150 (Preise). Wenn du lieber selbst eine Karriereseite erstellen willst, enthält ein kostenloses Konto die freien Teile wie Drawer und Search Input.

    Komponenten in diesem Artikel

    • Careers Page

      A React careers page template: mission, team mosaic, values, benefits, filterable open roles with a job drawer and apply form.

      Pro
    • Job Detail Page

      A React job posting page template: the role, benefits, interview steps, team, a sticky apply card, an application form and similar roles.

      Pro
    • Team Section

      A React team section for an about page: portrait cards, tall portrait cards, a compact roster or a list with bios, plus a "We're hiring" tile.

      Pro

    Häufige Fragen

    Was gehört auf eine Karriereseite?

    Eine Mission in einem Absatz, das Team, die Werte und Benefits, der Ablauf der Bewerbung und die offenen Stellen, nach Abteilung gruppiert, mit Ort, Art der Anstellung und Gehaltsspanne. Jede Stelle braucht eine eigene Seite mit der vollen Beschreibung und einem Bewerbungsformular, dazu kommt eine Initiativbewerbung für alle, die keine passende Stelle finden.

    Kann ich JobPosting Structured Data auf die Seite mit der Stellenliste setzen?

    Nein. Laut Googles Doku zu Stellenanzeigen darf das Markup nur auf Seiten stehen, die genau eine Stellenanzeige enthalten, und nicht auf Seiten, die Stellen auflisten. Setz es auf jede einzelne Stellenseite, etwa /careers/senior-frontend-engineer.

    Wie kennzeichne ich eine Remote-Stelle für Google for Jobs?

    Setz jobLocationType auf TELECOMMUTE und führ unter applicantLocationRequirements die Länder auf, in denen Bewerber wohnen dürfen. Google akzeptiert TELECOMMUTE nur für Stellen, die komplett remote sind, eine hybride Stelle behält also ihre Büroadresse in jobLocation.

    Was passiert mit einer Stellenanzeige, wenn die Stelle besetzt ist?

    Nimm sie offline: Liefere für die Seite einen 404 oder 410, entferne das Markup oder setz validThrough auf ein vergangenes Datum. Google warnt, dass abgelaufene Stellen, die online bleiben, zu einer manuellen Maßnahme führen können.

    Ist das Karriereseite Template von Wingo UI kostenlos?

    Nein. Careers Page, Job Detail Page, Team Section und der File Upload, den sie für Lebensläufe nutzen, sind Pro-Items. Andere Teile, auf denen sie aufbauen, wie Drawer, Search Input, Empty State und Marketing Section, sind kostenlos.

    In deinem Projekt ausprobieren

    Careers Page

    Pro

    A React careers page template: mission, team mosaic, values, benefits, filterable open roles with a job drawer and apply form.

    75 Komponenten kostenlos, ohne Konto. Pro ab 8 $ im Monat.

    Careers Page live öffnenPreise ansehen
    • Karriere
    • Vorlagen
    • Next.js
    • Strukturierte Daten

    Teilen

    SR

    Über den Autor

    Serban Rusu

    Gründer von Wingo UI

    Serban Rusu hat Wingo UI gegründet. Er baut die Komponenten, die CLI und den MCP-Server und schreibt über React-UIs für Smartphones und KI-Agents.

    Mehr von Serban
    Weiterlesen

    Ähnliche Artikel

    Alle Artikel
    Praxis: Screens und Apps

    SaaS Website Template: 7 Seiten neben der Startseite

    Ein SaaS Website Template braucht mehr als eine Startseite: was Preise, About, Karriere, Changelog, Kontakt, Recht und Vergleich leisten müssen, mit Next.js.

    SRSerban Rusu·5. Nov. 2026·19 Min. Lesezeit
    Praxis: Screens und Apps

    Agentur Website Template für Next.js: Vom Besuch zur Anfrage

    Ein Agentur Website Template für Next.js, das Briefings sammelt: Hero mit Wortwechsel, Leistungen, Case Studies, Ablauf, Team, Pakete und Anfrageformular.

    SRSerban Rusu·6. Nov. 2026·8 Min. Lesezeit
    Praxis: Screens und Apps

    AI SaaS Landing Page Template: 4 Abschnitte, die es braucht

    Ein AI SaaS Landing Page Template braucht vier Abschnitte, die normale SaaS-Seiten weglassen: eine Demo, die antwortet, Datenschutz, Nutzungspreise und Modelle.

    SRSerban Rusu·6. Nov. 2026·9 Min. Lesezeit
    Newsletter

    Neue Artikel per E-Mail

    Neue Artikel, Produktneuheiten und gelegentlich Angebote von Wingo UI. Wir zählen Klicks, damit es relevant bleibt.

    Kein Spam. Du kannst dich jederzeit abmelden.

    WingoUI

    Animierte, konfigurierbare, mobile-first React-Komponenten und Blöcke. Kopier den Quellcode, pass ihn an und lass deinen Coding-Agenten damit bauen.

    Produkt

    • Komponenten
    • Vorlagen
    • Preise
    • KI-Agenten
    • Für Teams
    • Theme-Generator

    Ressourcen

    • Doku
    • Kontakt
    • Programme
    • Blog
    • Changelog
    • Changelog-RSS
    • llms.txt

    Vergleiche

    • Wingo UI vs. Premium-Kits
    • Wingo UI vs. shadcn/ui
    • shadcn/ui-Alternativen
    • MUI-Alternativen
    • Tailwind-Plus-Alternativen
    • Magic-UI-Alternativen
    • Kostenlose Komponenten

    Rechtliches

    • AGB
    • Datenschutz
    • Rückerstattung
    • Lizenz
    • Impressum

    Komponenten-Kategorien

    • Buttons & Actions
    • Inputs
    • Forms
    • Navigation
    • Overlays
    • Feedback
    • Data Display
    • Tables & Lists
    • Charts & Stats
    • Layout
    • Media
    • AI Kit
    • Text & Effects
    • Mobile
    • Commerce
    • Marketing Sections
    • Blocks
    • Hooks & Utilities

    © 2026 Wingo UI

    Wingo UI