Filters
Search filters let you narrow photo and video results by orientation, size, color, category, dimensions, and more. Filters are capability-gated per provider — unsupported filters throw MediaError and are never silently ignored.
Installation
pnpm add @media-sdk/core@^0.3.0Filter types
PhotoSearchFilters
interface PhotoSearchFilters {
orientation?: "landscape" | "portrait" | "square";
size?: "large" | "medium" | "small";
color?: PhotoColor | PixabayColor;
category?: string;
minWidth?: number;
minHeight?: number;
editorsChoice?: boolean;
locale?: string;
}VideoSearchFilters
interface VideoSearchFilters {
orientation?: "landscape" | "portrait" | "square";
size?: "large" | "medium" | "small";
category?: string;
minWidth?: number;
minHeight?: number;
editorsChoice?: boolean;
locale?: string;
}Pass filters on SearchParams via photoFilters or videoFilters:
await client.searchPhotos({
query: "mountains",
page: 1,
perPage: 20,
photoFilters: { orientation: "landscape" },
});
await client.searchVideos({
query: "ocean",
page: 1,
perPage: 15,
videoFilters: { orientation: "landscape", size: "medium" },
});Provider mapping
Each client maps supported filter fields to its wire API. Unsupported fields throw before the HTTP request is sent.
| Filter | Pexels photos | Pexels videos | Pixabay photos | Pixabay videos |
|---|---|---|---|---|
orientation | ✅ | ✅ | ✅ | ❌ |
size | ✅ | ✅ | ❌ | ❌ |
color | ✅ | ❌ | ✅ | ❌ |
category | ❌ | ❌ | ✅ | ✅ |
minWidth / minHeight | ❌ | ❌ | ✅ | ✅ |
editorsChoice | ❌ | ❌ | ✅ | ✅ |
locale | ✅ | ✅ | ✅ | ❌ |
See the provider comparison matrix for the full capability table.
Examples by provider
import { ApiKeyProvider, PexelsMediaClient } from "@media-sdk/core";
const pexels = new PexelsMediaClient(
new ApiKeyProvider(process.env.PEXELS_API_KEY!),
);
await pexels.searchPhotos({
query: "mountains",
page: 1,
perPage: 20,
photoFilters: {
orientation: "landscape",
size: "large",
color: "green",
locale: "en-US",
},
});import { ApiKeyProvider, PixabayMediaClient } from "@media-sdk/core";
const pixabay = new PixabayMediaClient(
new ApiKeyProvider(process.env.PIXABAY_API_KEY!),
);
await pixabay.searchPhotos({
query: "nature",
page: 1,
perPage: 20,
photoFilters: {
orientation: "landscape",
color: "green",
category: "nature",
minWidth: 1920,
minHeight: 1080,
editorsChoice: true,
locale: "en",
},
});await pexels.searchVideos({
query: "ocean",
page: 1,
perPage: 15,
videoFilters: {
orientation: "landscape",
size: "medium",
locale: "en-US",
},
});Capability-gated UI
Check getCapabilities before sending user-selected filters. Build the filter object from flags that are true:
import {
getCapabilities,
type MediaClient,
type PhotoSearchFilters,
} from "@media-sdk/core";
async function searchWithFilters(
client: MediaClient,
query: string,
ui: {
orientation?: PhotoSearchFilters["orientation"];
size?: PhotoSearchFilters["size"];
category?: string;
},
) {
const caps = getCapabilities(client);
const photoFilters: PhotoSearchFilters = {};
if (ui.orientation && caps.photoFilters.orientation) {
photoFilters.orientation = ui.orientation;
}
if (ui.size && caps.photoFilters.size) {
photoFilters.size = ui.size;
}
if (ui.category && caps.photoFilters.category) {
photoFilters.category = ui.category;
}
return client.searchPhotos({
query,
page: 1,
perPage: 20,
photoFilters,
});
}In React, use useMediaCapabilities — hooks forward photoFilters / videoFilters to core without stripping unsupported keys, so capability checks belong in your UI layer.
Error codes
Filters fail fast with typed errors. The SDK never silently ignores an unsupported or invalid filter.
UNSUPPORTED_FILTER
Thrown when a filter key is not supported by the active provider or media type:
import { MediaError } from "@media-sdk/core";
try {
await pixabay.searchPhotos({
query: "nature",
photoFilters: { size: "large" }, // Pixabay photos do not support size
});
} catch (error) {
if (error instanceof MediaError && error.code === "UNSUPPORTED_FILTER") {
console.error("Filter not supported:", error.message);
// Filter "size" is not supported by this provider
}
}INVALID_FILTER_VALUE
Thrown when a filter key is supported but the value is invalid for that provider:
try {
await pexels.searchPhotos({
query: "nature",
photoFilters: { color: "grayscale" }, // Pexels-only color set
});
} catch (error) {
if (error instanceof MediaError && error.code === "INVALID_FILTER_VALUE") {
console.error("Invalid filter value:", error.message);
}
}Branch on error.code, not error.message. See Errors.
Anti-patterns
// ❌ Do not strip filters silently based on provider name
if (provider === "pixabay") {
delete filters.size;
}
// ✅ Gate on capabilities
if (!caps.photoFilters.size) {
delete filters.size;
}// ❌ Do not send filters hoping the client ignores them
await client.searchPhotos({
query: "nature",
photoFilters: { size: "large" }, // throws on Pixabay
});
// ✅ Check capabilities first, or handle UNSUPPORTED_FILTERRelated pages
- Capabilities —
photoFilters/videoFiltersflags - Errors — full error taxonomy
- Provider comparison — per-provider filter support