Affiliate & Partner Links
Affiliate & Partner Links
The myProp portal can display affiliate and partner links provided by the agency on dashboard pages for landlords, tenants, and buyers. These links are fetched in real time from the AgentOS API and rendered as a responsive card grid.
Overview
Affiliate links are configured at the agency level within AgentOS and are person-type-specific. Each link can include:
- A name / partner title
- A short description of the offering
- A URL that opens in a new tab
- An optional logo image
If an agency has not configured any affiliate links, or if the feature is disabled via a feature flag, the section does not appear in the portal — no empty state or placeholder is shown.
Supported Person Types
Affiliate links are fetched per person type. The following types are supported:
| Value | Used for |
|---|---|
landlord | Landlord portal dashboard |
tenant | Tenant portal dashboard |
buyer | Buyer portal dashboard |
Using the Component
The AffiliateLinksSection component can be embedded in any portal dashboard page. It handles its own data fetching, loading state, and error handling.
import { AffiliateLinksSection } from "@/components/affiliate-links";
// On a landlord dashboard
<AffiliateLinksSection
companySlug="acme-lettings"
personType="landlord"
/>
// With a custom heading and description
<AffiliateLinksSection
companySlug="acme-lettings"
personType="tenant"
title="Useful Services"
description="Recommended by your letting agent."
/>
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
companySlug | string | ✅ | — | The agency's URL slug / short name |
personType | "landlord" | "tenant" | "buyer" | ✅ | — | The portal user's person type |
title | string | ❌ | "Partner Links" | Section heading override |
description | string | ❌ | — | Optional sub-heading text |
Behaviour
- Loading — a spinner is shown while the request is in flight.
- No links / disabled — the component renders nothing (returns
null). - Error — silently renders nothing; errors are captured for observability but not shown to the user.
- Links open in a new tab with
rel="noopener noreferrer sponsored". - Results are cached client-side for 5 minutes (
staleTime: 300_000).
tRPC Endpoints
The component uses the affiliate tRPC router, registered in appRouter.
affiliate.status
Checks whether the affiliate links service is available (i.e. the AgentOS API client is configured).
const { data } = trpc.affiliate.status.useQuery();
// data: { available: boolean }
affiliate.list
Fetches affiliate links for a given company and person type.
const { data } = trpc.affiliate.list.useQuery({
shortName: "acme-lettings",
personType: "landlord",
});
// data: { links: AffiliateLink[], hidden: boolean }
Input schema:
| Field | Type | Description |
|---|---|---|
shortName | string | Agency short name / URL slug |
personType | "landlord" | "tenant" | "buyer" | Person type to fetch links for |
Response shape:
| Field | Type | Description |
|---|---|---|
links | AffiliateLink[] | Sorted list of affiliate links (empty if none or hidden) |
hidden | boolean | true if the feature flag suppressed the result |
AffiliateLink type
interface AffiliateLink {
id: string; // Unique identifier from AgentOS
name: string; // Partner display name
description: string | null;
url: string; // Target URL
imageUrl: string | null; // Partner logo URL
sortOrder: number; // Display order (ascending)
personType: AffiliatePersonType;
metadata: Record<string, unknown>; // Raw extra fields from API
}
Feature Flag
Agencies can disable affiliate links entirely using the RemoveAffiliateLinks company feature flag in their AgentOS configuration.
When this flag is true:
- The
affiliate.listtRPC endpoint returns{ links: [], hidden: true }immediately, without calling the AgentOS API. - The
AffiliateLinksSectioncomponent renders nothing.
This flag is read from the existing feature overrides system (src/lib/letmc/features.ts) and requires no additional configuration in myProp.
AgentOS API
Affiliate links are fetched from:
GET /v3/{shortName}/advertising/affiliatelinks/{personType}
The service handles two response shapes returned by the API:
- A direct JSON array:
AffiliateRecord[] - A wrapped object:
{ Data: AffiliateRecord[], Count: number }
A 404 response (no links configured for this agency/type) is treated as an empty result rather than an error.