Jobs

Building a job board with Next.js

Model companies, categories, and jobs in Prisma and keep unpaid submissions off the public board.

2 min read

A job board is a directory with a company on every row and, usually, a payment before the row is public. The Job Board Starter is Next.js 15 and Prisma 6 on SQLite. Payment is a separate article: accepting paid job submissions with Stripe.

Models

model Company {
  id      String @id @default(cuid())
  slug    String @unique
  name    String
  website String
  jobs    Job[]
}

model Category {
  id   String @id @default(cuid())
  slug String @unique
  name String
  jobs Job[]
}

model Job {
  id          String   @id @default(cuid())
  slug        String   @unique
  title       String
  location    String
  description String
  status      String   @default("pending")
  paid        Boolean  @default(false)
  companyId   String
  categoryId  String
  createdAt   DateTime @default(now())
}

status and paid are different. A job can be paid and still unpublished, or you can set both in the same update when Checkout succeeds. The kit’s return handler sets paid: true and status: "published" together after Stripe reports payment_status === "paid".

Public pages

Give a job /jobs/[slug] and a company /companies/[slug]. Look up by slug, include the company and category, and notFound() unless the job is published. The same Next.js 15 rule as the directory applies: params is a Promise. See building a directory with Next.js for the metadata function. Job descriptions are the body; the title is the <h1>. Do not use the description as the document title.

The board filters by text and category. Run that filter in the server component that renders the index, and paginate. Location is a string on the kit ("Remote" in the sample), not a geo point. Do not pretend it is a radius search.

Submission

/submit creates the company if needed, creates the job as pending, and then starts Checkout when a price id is configured. Until the paid handler runs, the job must not appear on the public index. Query where: { status: "published" } on the list. Filtering only in the UI still ships the pending rows to the browser.

Want to skip the setup? The Job Board Starter already includes companies, categories, job pages, and a pending status for new submissions.

Product updates for developers shipping with Designyff kits.

Purchased source may be used in personal, commercial, and client projects. Do not redistribute or resell the original source. Terms of Service

Designyff © 2026 | Starter kits for developers | Powered by  Tacko