The data layer manages all interactions with Yext APIs and handles state management for the search functionality. It provides a clean interface between the UI components and the underlying data services.
Manages the application's search state using URL parameters for persistence and shareability.
- URL-based state management
- Search settings serialization
- State synchronization
- Default value handling
// Default search settings
const defaultSearchSettings = {
input: '',
offset: 0,
limit: 16,
filters: {},
facetFilters: {},
sortBys: [{ type: 'RELEVANCE' }]
};
// State management functions
export const getStoredSearchSettings = () => {
// Retrieves search settings from URL
};
export const setStoredSearchSettings = (searchSettings: SearchSettings) => {
// Updates URL with new search settings
};
// Search Settings
interface SearchSettings {
input: string;
limit: number;
offset: number;
filters: QueryParam;
facetFilters: QueryParam;
sortBys: SortBy[];
verticalKey?: string;
}
// API Response Types
interface ResponseContent {
input: { value: string };
results: Result[];
facets?: Facet[];
totalResults: number;
}
// Entity Types
interface ResultItemData {
id: string;
type: string;
name: string;
description?: string;
c_photo?: string;
address?: Address;
// Additional fields based on entity type
}
// Facet Types
interface Facet {
fieldId: string;
displayName: string;
options: FacetOption[];
}
interface FacetOption {
value: string;
displayName: string;
count: number;
selected: boolean;
}
-
User Input
// Component triggers search searchStore.setStoredSearchSettings({ input: searchQuery, offset: 0 });
-
State Update
// URL parameters are updated updateUrlParameters(newParams, 'yext_');
-
API Request
// API call is made with current settings const response = await fetchSearchResults(getStoredSearchSettings());
-
Filter Selection
// Update filters in store searchStore.setStoredSearchSettings({ ...currentSettings, filters: newFilters });
-
Results Update
// Trigger new search with updated filters await refreshSearchResults();
interface UniversalSearchResponse {
businessId: number;
queryId: string;
modules: Module[];
}
async function performUniversalSearch(settings: SearchSettings) {
// Implementation
}
interface VerticalSearchResponse {
businessId: number;
queryId: string;
resultsCount: number;
results: VerticalSearchResult[];
}
async function performVerticalSearch(vertical: string, settings: SearchSettings) {
// Implementation
}
- All Yext-related parameters are prefixed with
yext_
- Complex objects are serialized to JSON strings
- State changes trigger URL updates
- Browser history is maintained
- Support for React state integration
https://example.com/search
?yext_input=query
&yext_offset=0
&yext_limit=20
&yext_verticalKey=locations
&yext_filters={"location":{"$eq":"New York"}}
// Example React state integration
function useYextSearch() {
const [searchState, setSearchState] = useState<SearchSettings>(defaultSearchSettings);
useEffect(() => {
// Sync URL parameters with React state
const params = new URLSearchParams(window.location.search);
const newState = parseSearchParams(params);
setSearchState(newState);
}, []);
return { searchState, setSearchState };
}
interface ApiError {
code: string;
message: string;
details?: unknown;
}
function handleApiError(error: ApiError) {
// Error handling implementation
}
function handleStateError(error: Error) {
// State error handling
console.error('State management error:', error);
}
const searchResultsCache = new Map<string, SearchResponse>();
function getCachedResults(key: string) {
return searchResultsCache.get(key);
}
async function batchProcessResults(results: Result[]) {
// Batch processing implementation
}
describe('YextStore', () => {
it('should properly serialize search settings', () => {
// Test implementation
});
it('should handle state updates correctly', () => {
// Test implementation
});
});
describe('API Integration', () => {
it('should handle API responses correctly', () => {
// Test implementation
});
});
- Always use type-safe operations
- Maintain atomic updates
- Handle edge cases gracefully
- Implement proper error boundaries
- Implement proper retry logic
- Handle rate limiting
- Cache responses when appropriate
- Validate API responses
- Minimize state updates
- Implement efficient caching
- Use batch processing
- Optimize API calls
- Secure API key management
- Request validation
- Response sanitization
- Error handling security
- Input validation
- Output encoding
- State validation
- URL parameter validation