Companies

Build company directories, market pages, profiles, and company-specific job lists.

Build a public employer directory and a canonical company page that combines the company profile with its current jobs. Public company reads do not expose employer-management records.

Prerequisites

  • A shared public board client.
  • Routes for /companies and /companies/:companySlug.
  • Optional market routes at /companies/markets/:marketSlug.

Load the directory and profile

ts
// src/data/companies.ts
import { isNotFound } from '@cavuno/board';
import { companyMarketPath, companyPath } from '@cavuno/board/paths';
import { board } from '../lib/board';
export async function loadCompanyDirectory(marketSlug?: string) {
const [companies, markets] = await Promise.all([
board.companies.list({ limit: 24, marketSlug }),
board.companies.markets({ limit: 100 }),
]);
return {
companies: companies.data.map((company) => ({
...company,
path: companyPath(company.slug),
})),
markets: markets.data,
nextCursor: companies.nextCursor,
};
}
export async function loadCompanyPage(companySlug: string) {
try {
const [company, jobs, similar] = await Promise.all([
board.companies.retrieve(companySlug),
board.companies.listJobs(companySlug, { limit: 20 }),
board.companies.similar(companySlug, { limit: 6 }),
]);
return {
company,
jobs: jobs.data,
similar: similar.data,
canonicalPath: companyPath(company.slug),
};
} catch (error) {
if (isNotFound(error)) return null;
throw error;
}
}

The directory response contains summaries. retrieve adds the company’s markets. listJobs returns the same slim job cards as the main jobs catalog, including catalog pagination fields when available.

Resolve market aliases

Market URLs can arrive in a board-language or legacy form. Resolve the inbound slug before rendering the page:

ts
const market = await board.companies.markets.resolve(inboundMarketSlug);
if (market.redirectTo) {
// Return a permanent redirect with your framework.
return { redirectTo: companyMarketPath(market.redirectTo) };
}

Wrap the exact canonical slug returned in redirectTo with the market path helper. Do not derive a replacement slug from the display name.

Expected result

The directory contains company summaries, market filters, and a next cursor. A company detail response includes its markets, current jobs, related companies, and one canonical path.

Verify the result

  • /companies shows real company names and published-job counts.
  • A market selection scopes board.companies.list with marketSlug.
  • The profile route returns a 404 for an unknown company.
  • The profile’s canonical path matches companyPath(company.slug).

Errors and edge cases

  • Unknown market slugs can return 404. Resolve aliases before treating them as missing.
  • Company search is a POST: board.companies.search({ query: 'Acme' }).
  • similar excludes the current company and defaults to six results.
  • A company can have zero published jobs. Keep the company profile useful without inventing openings.
  • Public methods are not a substitute for board.me.companies, which requires an employer session.

Production checklist

  • Paginate the directory rather than collecting every company in a browser request.
  • Keep company slugs canonical and emit permanent redirects for resolved aliases.
  • Link jobs with the canonical path helpers.
  • Add company and market pages to the generated sitemap.

Next, add editorial content with Blog, or continue to Candidate accounts and talent.