# Experts Page

> A Hire an Expert directory: search, filters and sort over certified consultants and agencies, profiles, proposal requests and a matcher.

- Type: React template (Templates)
- Access: Pro (the source needs a Wingo UI Pro plan, see https://wingo-ui.com/pricing)
- Version: 1.0.0
- Install: `npx wingo-ui@latest add experts-page`
- Docs: https://wingo-ui.com/templates/experts-page

## Interaction

The hero rises in once beside a drawn cluster of expert profile cards (an Elite agency with its rating, services and starting price, a Premier consultant tilted behind, and on wide screens a proposal-sent chip and a five-star review). The search bar filters the directory as you type; the Location and Budget selects set the region and price filters, Find experts (or Enter) scrolls to the directory, and the Popular chips pick one service. On desktop a sidebar holds the filters: service checkboxes with live counts, a two-thumb starting price slider, tier, region, language and industry chips (options with no matches are disabled) and an Available now switch; on phones and tablets a Filters button (with the active count) opens a full-height bottom sheet whose filters apply only on Show N experts. Active filters show as removable chips with Clear all; Sort picks Recommended, Highest rated or Price low to high; cards animate into place, eight show before Show more, and no match shows an empty state with Clear all. Any card (the whole card is one target) opens the profile: a large dialog on desktop and a bottom sheet on phones with the about text, packages with price ranges, case studies drawn as before and after boards, a rating breakdown and reviews, and a facts panel. Request a proposal swaps in a form (project type, budget, timeline, description, name, work email) that checks every field, shows the errors under them and focuses the first; Send spins while onRequest runs, a rejection shows an error, then a success view names who replies and when, and the card shows Request sent. The matcher asks three questions as big choice tiles with a progress bar and Back, then ranks the top three experts with animated match bars that open their profiles; Start over resets it. Steps, the Elite agencies rail (snap scrolling on phones), customer quotes, FAQ, the Become an Acme Expert band and the closing call follow. Reduced motion keeps everything still.

## Installation

```bash
npx wingo-ui@latest add experts-page
```

Pro item: run `npx wingo-ui@latest login` once with a Pro account. The CLI adds the files, their dependencies and a version record for updates.

With shadcn: `npx shadcn@latest add @wingo-ui/experts-page` (needs the @wingo-ui registry with your API key in components.json)

Files:

- `components/templates/experts-page.tsx`
- `components/templates/experts-page-data.ts`

npm dependencies: `npm i lucide-react motion`

Wingo UI dependencies (installed automatically):

- [Marketing Section](https://wingo-ui.com/components/marketing-section) ([Markdown](https://wingo-ui.com/components/marketing-section.md))
- [Marketing Header](https://wingo-ui.com/components/marketing-header) ([Markdown](https://wingo-ui.com/components/marketing-header.md))
- [Marketing Footer](https://wingo-ui.com/components/marketing-footer) ([Markdown](https://wingo-ui.com/components/marketing-footer.md))
- [Steps Section](https://wingo-ui.com/components/steps-section) ([Markdown](https://wingo-ui.com/components/steps-section.md))
- [Testimonials Section](https://wingo-ui.com/components/testimonials-section) ([Markdown](https://wingo-ui.com/components/testimonials-section.md))
- [FAQ Section](https://wingo-ui.com/components/faq-section) ([Markdown](https://wingo-ui.com/components/faq-section.md))
- [CTA Section](https://wingo-ui.com/components/cta-section) ([Markdown](https://wingo-ui.com/components/cta-section.md))
- [Avatar](https://wingo-ui.com/components/avatar) ([Markdown](https://wingo-ui.com/components/avatar.md))
- [Badge](https://wingo-ui.com/components/badge) ([Markdown](https://wingo-ui.com/components/badge.md))
- [Button](https://wingo-ui.com/components/button) ([Markdown](https://wingo-ui.com/components/button.md))
- [Checkbox](https://wingo-ui.com/components/checkbox) ([Markdown](https://wingo-ui.com/components/checkbox.md))
- [Dialog](https://wingo-ui.com/components/dialog) ([Markdown](https://wingo-ui.com/components/dialog.md))
- [Drawer](https://wingo-ui.com/components/drawer) ([Markdown](https://wingo-ui.com/components/drawer.md))
- [Empty State](https://wingo-ui.com/components/empty-state) ([Markdown](https://wingo-ui.com/components/empty-state.md))
- [Field](https://wingo-ui.com/components/field) ([Markdown](https://wingo-ui.com/components/field.md))
- [Input](https://wingo-ui.com/components/input) ([Markdown](https://wingo-ui.com/components/input.md))
- [Rating](https://wingo-ui.com/components/rating) ([Markdown](https://wingo-ui.com/components/rating.md))
- [Search Input](https://wingo-ui.com/components/search-input) ([Markdown](https://wingo-ui.com/components/search-input.md))
- [Select](https://wingo-ui.com/components/select) ([Markdown](https://wingo-ui.com/components/select.md))
- [Slider](https://wingo-ui.com/components/slider) ([Markdown](https://wingo-ui.com/components/slider.md))
- [Switch](https://wingo-ui.com/components/switch) ([Markdown](https://wingo-ui.com/components/switch.md))
- [Tag](https://wingo-ui.com/components/tag) ([Markdown](https://wingo-ui.com/components/tag.md))
- [Textarea](https://wingo-ui.com/components/textarea) ([Markdown](https://wingo-ui.com/components/textarea.md))
- [useControllableState](https://wingo-ui.com/components/use-controllable-state) ([Markdown](https://wingo-ui.com/components/use-controllable-state.md))
- [Motion presets](https://wingo-ui.com/components/motion) ([Markdown](https://wingo-ui.com/components/motion.md))
- [Navigation](https://wingo-ui.com/components/navigation) ([Markdown](https://wingo-ui.com/components/navigation.md))
- [Text match](https://wingo-ui.com/components/text-match) ([Markdown](https://wingo-ui.com/components/text-match.md))
- [Tones](https://wingo-ui.com/components/tones) ([Markdown](https://wingo-ui.com/components/tones.md))
- [UIProvider](https://wingo-ui.com/components/ui-config) ([Markdown](https://wingo-ui.com/components/ui-config.md))

## Usage

```tsx
// app/(marketing)/experts/page.tsx
"use client"

import Link from "next/link"
import { ExpertsPage } from "@/components/templates/experts-page"

export default function ExpertsRoute() {
  return (
    <ExpertsPage
      linkComponent={Link}
      ctaTone="brand"
      onRequest={async (expert, values) => {
        const response = await fetch("/api/experts/requests", {
          method: "POST",
          body: JSON.stringify({ expertId: expert.id, ...values }),
        })
        if (!response.ok) throw new Error("Could not send the request")
      }}
    />
  )
}
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `design?` | `"classic" \| "bold" \| "minimal"` | `"classic"` | The whole page's look. classic follows the layout props: a split hero with drawn profile cards over a dotted glow; bold: a pill header, a giant stage title on a gradient mesh, rounder cards, an inverted Elite panel, step cards, a quote wall, FAQ cards, a band and a wordmark footer; minimal: a transparent header, a centered quiet hero without cards, flat outlined cards, no gray bands and a simple footer. The *Props overrides still win. |
| `experts?` | `Expert[]` | `"EXPERTS"` | The directory: { id, name, kind, tagline, about, location, region, timeZone, languages, services, industries, startingPrice, rating, reviewCount, projects, responseHours, tier, availableNow, availability, contact, packages, caseStudies, reviews, ... }. |
| `services?` | `ExpertOption[]` | `"EXPERT_SERVICES"` | Service filter options and matcher answers: { value, label, description? }. |
| `industries?` | `ExpertOption[]` | `"EXPERT_INDUSTRIES"` | Industry filter chips and matcher answers. |
| `languages?` | `ExpertOption[]` | `"EXPERT_LANGUAGES"` | Language filter chips; expert languages are these values. |
| `regions?` | `ExpertOption[]` | `"EXPERT_REGIONS"` | Region filter chips and the hero's Location select. |
| `tiers?` | `ExpertOption[]` | `"EXPERT_TIERS"` | Elite, Premier and Certified, with their badge labels. |
| `budgets?` | `ExpertsBudgetOption[]` | `"EXPERTS_BUDGETS"` | The hero's Budget select and the matcher's budget answers: { value, label, min, max } in USD. |
| `quickSearches?` | `ExpertsQuickSearch[]` | `"EXPERTS_QUICK_SEARCHES"` | The Popular chips under the search bar: { label, service }. |
| `proposalBudgets?` | `ExpertOption[]` | `"EXPERTS_PROPOSAL_BUDGETS"` | The proposal form's budget ranges; empty drops the field. |
| `timelines?` | `ExpertOption[]` | `"EXPERTS_TIMELINES"` | The proposal form's timeline options; empty drops the field. |
| `heroExperts?` | `string[]` | `"EXPERTS_HERO"` | Expert ids drawn in the hero: [front card, back card, review]. |
| `steps?` | `StepsSectionItem[]` | `"EXPERTS_STEPS"` | How hiring works: { icon?, title, description, meta? }. |
| `testimonials?` | `Testimonial[]` | `"EXPERTS_TESTIMONIALS"` | Customers who hired experts: { quote, name, role?, company?, companyIcon?, rating?, metric? }. |
| `faq?` | `FaqItem[]` | `"EXPERTS_FAQ"` | { question, answer } pairs about hiring an expert. |
| `becomePerks?` | `string[]` | `"EXPERTS_BECOME_PERKS"` | The three lines in the Become an Acme Expert band. |
| `labels?` | `Partial<ExpertsPageLabels>` | `"DEFAULT_EXPERTS_PAGE_LABELS"` | Every visible string; the ones with numbers or names in them are functions. |
| `hrefs?` | `Partial<ExpertsPageHrefs>` | `"DEFAULT_EXPERTS_PAGE_HREFS"` | { directory, matcher, become, requirements, sales, privacy }. |
| `query?` | `string` |  | The controlled search text; pair it with onQueryChange. |
| `defaultQuery?` | `string` | `""` | The search text on load. |
| `onQueryChange?` | `(query: string) => void` |  | Every keystroke in the search bar. |
| `filters?` | `ExpertsFilters` |  | The controlled filters: { services, industries, languages, regions, tiers, budget: [min, max], availableNow }. |
| `defaultFilters?` | `Partial<ExpertsFilters>` |  | The filters on load, merged over DEFAULT_EXPERTS_FILTERS. |
| `onFiltersChange?` | `(filters: ExpertsFilters) => void` |  | Any filter changed (the phone sheet reports on Apply). |
| `sort?` | `"recommended" \| "rating" \| "price"` |  | The controlled sort; pair it with onSortChange. |
| `defaultSort?` | `"recommended" \| "rating" \| "price"` | `"recommended"` | The sort on load: tier, rating and availability; highest rated; or price low to high. |
| `onSortChange?` | `(sort: ExpertSort) => void` |  | The sort changed. |
| `pageSize?` | `number` | `8` | Cards shown before Show more; 0 shows every match. |
| `loading?` | `boolean` | `false` | The directory shows card skeletons. |
| `onRequest?` | `(expert: Expert, values: ExpertProposalRequest) => (void \| Promise<unknown>)` |  | A proposal request: { projectType, budget, timeline, description, name, email }. A promise keeps Send loading and a rejection shows an error. Without it the form waits 900 ms and shows the success view. |
| `onExpertOpen?` | `(expert: Expert) => void` |  | A profile was opened (analytics, a URL update). |
| `showQuickSearches?` | `boolean` | `true` | The Popular chips under the search bar. |
| `showHeroCards?` | `boolean` | `true` | The drawn profile cards in the hero (classic and bold). |
| `showMatcher?` | `boolean` | `true` | The three-question matcher. |
| `showSteps?` | `boolean` | `true` | How hiring works. |
| `showElite?` | `boolean` | `true` | The featured Elite agencies. |
| `showTestimonials?` | `boolean` | `true` | The customer quotes. |
| `showFaq?` | `boolean` | `true` | The FAQ. |
| `showBecome?` | `boolean` | `true` | The Become an Acme Expert band linking to /partners. |
| `showCta?` | `boolean` | `true` | The closing call to action. |
| `stepsLayout?` | `"horizontal" \| "cards" \| "vertical"` | `"horizontal"` | How hiring works as a numbered row, numbered tiles or a timeline rail. Applies to the classic design. |
| `testimonialsLayout?` | `"featured" \| "grid" \| "carousel" \| "marquee"` | `"featured"` | Customer quotes as one big quote and two small, a grid, a swipeable rail or drifting rows. Applies to the classic design. |
| `ctaVariant?` | `"inverted" \| "soft" \| "split"` | `"inverted"` | The closing band: a solid band, a gray band, or copy beside the buttons. Applies to the classic design. |
| `alternate?` | `boolean` | `true` | Gray bands on every other section. Applies to the classic and bold designs. |
| `tone?` | `"neutral" \| "brand" \| "success" \| "warning" \| "danger" \| "info"` | `"neutral"` | Accents: the hero glow, Elite badges, stars, rating bars, match bars, selected chips and checkboxes, the price slider. |
| `ctaTone?` | `"neutral" \| "brand" \| "success" \| "warning" \| "danger" \| "info"` | `"neutral"` | Find experts, Request a proposal, Send request, Apply in the filter sheet, the header's Get started and the closing band; brand is the marketing orange. |
| `radius?` | `"none" \| "sm" \| "md" \| "lg" \| "full"` | `"md"` | The corners of the search bar fields, the sort select and the proposal form fields. |
| `header?` | `boolean` | `true` | The marketing header; off inside a site layout. |
| `footer?` | `boolean` | `true` | The marketing footer with its newsletter form. |
| `headerProps?` | `Partial<MarketingHeaderProps>` |  | Passed to MarketingHeader. |
| `footerProps?` | `Partial<MarketingFooterProps>` |  | Passed to MarketingFooter. |
| `stepsProps?` | `Partial<StepsSectionProps>` |  | Overrides for the StepsSection. |
| `testimonialsProps?` | `Partial<TestimonialsSectionProps>` |  | Overrides for the TestimonialsSection. |
| `faqProps?` | `Partial<FaqSectionProps>` |  | Overrides for the FaqSection. |
| `ctaProps?` | `Partial<CtaSectionProps>` |  | Overrides for the CtaSection. |
| `onSubscribe?` | `(email: string) => (void \| Promise<unknown>)` |  | The footer newsletter; a rejected promise shows an error. |
| `animateIn?` | `boolean` | `true` | The hero rises in once and the profile cards tilt into place; false keeps the page still (thumbnails). Reduced motion always does. |
| `locale?` | `string` | `"en-US"` | Intl locale for the USD prices, ratings, counts and review dates. |
| `linkComponent?` | `(props: LinkComponentProps) => ReactNode` | `"<a>"` | The router link for every link on the page (next/link in an app). |
| `className?` | `string` |  | Classes for the root. |
| `classNames?` | `Partial<Record<ExpertsPageSlot, string>>` |  | Classes for header, hero, title, search, cluster, directory, sidebar, toolbar, chips, grid, card, profile, form, matcher, steps, elite, testimonials, faq, become, cta and footer. |

## Parts

### EXPERTS_PAGE_SAMPLE (constant)

All the sample content in one object: experts, filter options, budgets, quick searches, form options, hero ids, steps, testimonials, faq and perks.

### EXPERTS (constant)

Sixteen fictional experts: agencies like Brightside Ops, Northpeak Studio and Fieldwork Collective, and independents across four regions.

### EXPERT_SERVICES (constant)

Migration, Automations, Team training, Custom integrations, Workspace setup and Reporting.

### EXPERT_INDUSTRIES (constant)

Software, Agencies, Healthcare, Ecommerce, Finance and Nonprofits.

### EXPERT_LANGUAGES (constant)

Eight languages as { value, label }.

### EXPERT_REGIONS (constant)

North America, Latin America, Europe and Asia Pacific.

### EXPERT_TIERS (constant)

Elite, Premier and Certified with what each means.

### EXPERTS_BUDGETS (constant)

Any budget, under $2,500, $2,500 to $5,000 and $5,000 and up.

### EXPERTS_QUICK_SEARCHES (constant)

The four Popular chips.

### EXPERTS_PROPOSAL_BUDGETS (constant)

The proposal form's budget ranges.

### EXPERTS_TIMELINES (constant)

The proposal form's timelines.

### EXPERTS_HERO (constant)

The expert ids drawn in the hero.

### EXPERTS_STEPS (constant)

Tell us what you need, compare proposals, kick off with confidence.

### EXPERTS_TESTIMONIALS (constant)

Six quotes from customers who hired experts.

### EXPERTS_FAQ (constant)

Six questions about vetting, cost, fees, guarantees, security and retainers.

### EXPERTS_BECOME_PERKS (constant)

The perks listed in the Become an Acme Expert band.

### EXPERTS_BUDGET_MAX (constant)

10000: the price slider's end, read as "and up".

### EXPERTS_BUDGET_STEP (constant)

250: the price slider's step.

### DEFAULT_EXPERTS_FILTERS (constant)

No filters: every list empty, the full price range, availableNow false.

### getExpertMatch (function)

The matcher's score: (expert, { service?, industry?, budget? }, budgets?) => a 40 to 98 match percentage.

### getExpertRatingBreakdown (function)

(rating, count) => the review counts at 5, 4, 3, 2 and 1 stars, for the profile's bars.

### DEFAULT_EXPERTS_PAGE_LABELS (constant)

The English strings.

### DEFAULT_EXPERTS_PAGE_HREFS (constant)

The default link targets.

### EXPERTS_PAGE_DESIGNS (constant)

The design names, classic first: ["classic", "bold", "minimal"].

### ExpertsPageProps (type)

Props of ExpertsPage.

### ExpertsPageDesign (type)

"classic" | "bold" | "minimal".

### Expert (type)

One expert or agency in the directory.

### ExpertTier (type)

"certified" | "premier" | "elite".

### ExpertSort (type)

"recommended" | "rating" | "price".

### ExpertsFilters (type)

The directory's filters.

### ExpertProposalRequest (type)

The proposal form's values passed to onRequest.

### ExpertsPageLabels (type)

The strings labels can override.

### ExpertsPageHrefs (type)

The link targets hrefs can override.

## Examples

- **Bold design**: design="bold": a giant stage title on a gradient mesh, rounder cards, an inverted Elite panel, a quote wall and a wordmark footer.
- **Minimal design**: design="minimal": a transparent header, a centered quiet hero, flat outlined cards, no gray bands and a simple footer.
- **Pre-filtered in brand orange**: defaultFilters for migration experts available now, sorted by rating, with tone and ctaTone brand.
- **Loading directory**: loading: the directory shows card skeletons while experts load.
- **Request service down**: An onRequest that rejects: open a profile, request a proposal and send it to see the error while every value stays in place.

## See also

- [Affiliate Page](https://wingo-ui.com/templates/affiliate-page) ([Markdown](https://wingo-ui.com/templates/affiliate-page.md))
- [Template Gallery Page](https://wingo-ui.com/templates/template-gallery-page) ([Markdown](https://wingo-ui.com/templates/template-gallery-page.md))
- [Customers Page](https://wingo-ui.com/templates/customers-page) ([Markdown](https://wingo-ui.com/templates/customers-page.md))
- [Integrations Page](https://wingo-ui.com/templates/integrations-page) ([Markdown](https://wingo-ui.com/templates/integrations-page.md))
- [Testimonials Section](https://wingo-ui.com/components/testimonials-section) ([Markdown](https://wingo-ui.com/components/testimonials-section.md))

---

Canonical: https://wingo-ui.com/templates/experts-page
More components: https://wingo-ui.com/components · Index for agents: https://wingo-ui.com/llms.txt
