1 OAK MLS

Client Site

Public-facing agent website with listings, areas, and contact functionality

Client Site

The client site is the public-facing website for each agent, displaying their listings and brand.

Overview

Each workspace gets a client site that includes:

  • Homepage with hero, featured listing, and service areas
  • Listings page with faceted search and filtering
  • Area pages for geographic neighborhoods
  • Listing detail pages with photo gallery and property info
  • Contact page for lead capture

Route Structure

/
├── /                         # Homepage
├── /listings                 # Listings search
├── /listings/[id]            # Listing detail
├── /areas                    # Service areas index
├── /areas/[slug]             # Area detail + listings
├── /about                    # Agent bio
└── /contact                  # Contact form

Workspace Resolution

The client site determines which workspace to display using:

  1. Host header — Custom domain lookup in workspace_domains
  2. Query parameter?workspace=slug for development/preview
async function getWorkspaceFromHost(): Promise<Workspace | null> {
  const host = headers().get('host');

  // Check workspace_domains table
  const { data } = await supabase
    .from('workspace_domains')
    .select('workspace:workspaces(*)')
    .eq('domain', host)
    .single();

  return data?.workspace ?? null;
}

Homepage Sections

Hero Section

Full-width hero with:

  • Background image (customizable in settings)
  • Workspace name / agent tagline
  • Call-to-action buttons

Configuration in workspace.settings.site.hero:

interface HeroConfig {
  imageUrl?: string;   // Custom hero image
  tagline?: string;    // Hero subtitle text
}

Showcase a specific listing with:

  • Ken Burns animation on photos
  • Property details overlay
  • Link to full listing

Configuration in workspace.settings.site.featuredListing:

interface FeaturedListingConfig {
  enabled: boolean;
  listingId?: string;  // UUID of selected listing
}

Service Areas Section

Grid of neighborhood cards showing:

  • Area hero image
  • Name and tagline
  • Listing count
  • Starting price

Links to /areas/[slug] for each area.

Listings Page

Search & Filtering

The listings page provides:

  • Text search — Address, city, subdivision
  • Faceted filters — Property type, beds, baths, price range
  • Sort options — Newest, price low/high, beds
  • Listing source toggle — "My Listings" vs "All Listings"

Listing Source Filtering

By default, the listings page shows agent-affiliated listings:

  • import_category: personal — Agent's own listings
  • import_category: office — Brokerage listings

The "Show All Listings" toggle (if enabled) expands to include:

  • import_category: search — Service area imports

Configuration: workspace.settings.showAllListingsLink

Pagination

Server-side pagination with:

  • 24 listings per page
  • Page number in URL
  • Total count display

Area Pages

Areas Index (/areas)

Grid of all service areas showing:

  • Hero image or gradient
  • Area name
  • Tagline
  • Listing count
  • "From $X" pricing

Area Detail (/areas/[slug])

Dedicated page for each service area:

  • Hero section with area image
  • Description text (SEO)
  • Stats (count, price floor)
  • Filtered listing grid
  • Pagination
  • Contact CTA

Area pages always show all listings (including search imports) since users are browsing by location.

Listing Detail Page

  • Primary photo as hero
  • Thumbnail navigation
  • Lightbox for full-screen
  • Photo priority: uploads > MLS > placeholder

Property Information

Sections include:

  • Overview — Price, beds, baths, sqft
  • Location — Address, map (if enabled)
  • Description — Public remarks
  • Features & Amenities — From MLS data
  • Property Details — Year built, lot size, etc.

Contact Form

Inline contact form or CTA to contact page.

MLS Compliance

  • Attribution text from compliance_profiles
  • Disclaimer (if configured)
  • MLS number display

Responsive header with:

  • Logo/workspace name
  • Navigation links
  • Mobile hamburger menu

Navigation items:

  • Home
  • Listings
  • Areas (if service areas exist)
  • About
  • Contact

Footer includes:

  • Brokerage information
  • Social media links
  • MLS attribution
  • Legal disclaimer
  • Copyright

Theming

Workspaces can customize appearance via settings.theme:

Theme Presets

Built-in presets:

  • luxury — Dark, sophisticated
  • modern — Clean, minimal
  • coastal — Light, airy
  • classic — Traditional

Color Overrides

Custom colors for light/dark mode:

interface WorkspaceTheme {
  preset: ThemePresetId;
  colorOverrides?: {
    light?: Partial<ThemeColors>;
    dark?: Partial<ThemeColors>;
  };
}

CSS Variables

Theme colors are applied via CSS variables:

:root {
  --primary: hsl(var(--theme-primary));
  --background: hsl(var(--theme-background));
  /* ... */
}

Agent & Brokerage Info

Agent Profile

Displayed on About page and footer:

interface AgentInfo {
  name: string;
  title?: string;
  email?: string;
  phone?: string;
  photoUrl?: string;
  licenseNumber?: string;
  bio?: string;  // Markdown supported
}

Brokerage

Displayed in footer:

interface BrokerageInfo {
  name: string;
  logoUrl?: string;
  address?: string;
  phone?: string;
  website?: string;
}
interface SocialLinks {
  instagram?: string;
  facebook?: string;
  linkedin?: string;
  twitter?: string;
  youtube?: string;
  tiktok?: string;
}

SEO Configuration

Workspace-level SEO settings:

interface SeoConfig {
  title?: string;           // Default page title
  description?: string;     // Meta description
  ogImage?: string;         // Social share image
  keywords?: string[];
  googleAnalyticsId?: string;
  facebookPixelId?: string;
}

Feature Flags

Toggle features per workspace:

interface WorkspaceFeatures {
  favorites: boolean;        // Saved listings
  savedSearches: boolean;    // Search alerts
  virtualTours: boolean;     // Virtual tour links
  mapView: boolean;          // Map toggle
  socialSharing: boolean;    // Share buttons
  mortgageCalculator: boolean;
  neighborhoodData: boolean;
}

Development

Local Development

Run the client site locally:

pnpm --filter web dev

Use query parameter for workspace:

http://localhost:3000?workspace=lainey-levin

Preview Domains

For staging/preview without custom domain setup, use the query parameter approach or configure preview subdomains.

On this page