- Node.js (v16 or higher)
- Yarn package manager
- Yext API credentials
- TypeScript knowledge
- Web Components understanding
- React knowledge
-
Clone the Repository
git clone <repository-url> cd <project-directory>
-
Install Dependencies
yarn install
-
Environment Setup Create a
.env
file in the root directory:YEXT_API_KEY=your_api_key YEXT_BUSINESS_ID=your_business_id YEXT_ENV=production
src/
├── components/ # Web components and React components
│ ├── outline-yext-universal/
│ ├── outline-yext-vertical/
│ ├── outline-yext-pager/
│ ├── outline-yext-entities/
│ └── SearchContainer.tsx
├── libraries/ # Shared libraries
│ ├── data-access-yext/ # Yext API integration
│ └── ui-yext/ # UI components
├── controllers/ # Application controllers
├── stories/ # Storybook stories
└── tests/ # Test files
├── unit/
├── integration/
└── e2e/
yarn dev
yarn build
yarn test
-
Create Component Directory
mkdir src/components/my-new-component
-
Component Structure
// my-new-component.ts export class MyNewComponent extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); } connectedCallback() { this.render(); } render() { // Implementation } } customElements.define('my-new-component', MyNewComponent);
-
Unit Tests
// my-new-component.test.ts describe('MyNewComponent', () => { it('should render correctly', () => { // Test implementation }); });
-
Integration Tests
describe('MyNewComponent Integration', () => { it('should interact with other components', () => { // Test implementation }); });
// Example API client setup
const client = new YextClient({
apiKey: process.env.YEXT_API_KEY,
businessId: process.env.YEXT_BUSINESS_ID
});
// Example search request
async function performSearch(query: string) {
try {
const response = await client.search({
input: query,
// other parameters
});
return response;
} catch (error) {
handleError(error);
}
}
// Example state update
function updateSearchState(newState: SearchSettings) {
const params = new URLSearchParams();
Object.entries(newState).forEach(([key, value]) => {
params.set(`yext_${key}`, JSON.stringify(value));
});
updateUrlParameters(params);
}
class ErrorBoundary extends HTMLElement {
handleError(error: Error) {
console.error('Component error:', error);
this.render(); // Render fallback UI
}
}
// Example lazy loading implementation
async function loadComponent() {
const module = await import('./my-component');
return module.MyComponent;
}
// Example cache implementation
const cache = new Map();
function getCachedData(key: string) {
if (!cache.has(key)) {
cache.set(key, fetchData(key));
}
return cache.get(key);
}
- Open browser developer tools
- Navigate to Elements tab
- Inspect shadow DOM components
- Use console for debugging
- Check URL parameters for state
- Use browser console to view state changes
- Monitor network requests
yarn dev
# Starts development server with hot reloading
yarn build
# Creates optimized production build
yarn test
# Runs test suite
- Follow TypeScript best practices
- Use consistent naming conventions
- Document public APIs
- Write meaningful comments
- Create feature branch
- Make changes
- Write tests
- Update documentation
- Submit PR
-
API Authentication
- Check API key configuration
- Verify environment variables
- Check network requests
-
Component Rendering
- Inspect shadow DOM
- Check for JavaScript errors
- Verify component registration
-
State Management
- Check URL parameters
- Verify state updates
- Monitor state flow
// Enable debug logging
const DEBUG = true;
function log(message: string, data?: any) {
if (DEBUG) {
console.log(`[DEBUG] ${message}`, data);
}
}
-
Install Playwright
yarn add -D @playwright/test npx playwright install
-
Configure Playwright
// playwright.config.ts import { PlaywrightTestConfig } from '@playwright/test'; const config: PlaywrightTestConfig = { testDir: './tests/e2e', use: { baseURL: 'http://localhost:3000', screenshot: 'only-on-failure', }, webServer: { command: 'yarn dev', port: 3000, reuseExistingServer: !process.env.CI, }, }; export default config;
-
Run Tests
# Run all tests yarn test # Run e2e tests yarn test:e2e # Run unit tests yarn test:unit
-
E2E Tests
// tests/e2e/search.spec.ts import { test, expect } from '@playwright/test'; test('search functionality', async ({ page }) => { await page.goto('/'); await page.fill('[data-testid="search-input"]', 'test'); await expect(page.locator('.search-results')).toBeVisible(); });
-
Unit Tests
// tests/unit/components/SearchContainer.test.tsx import { render, screen } from '@testing-library/react'; import { SearchContainer } from '../../../components/SearchContainer'; test('renders search container', () => { render(<SearchContainer />); expect(screen.getByTestId('search-container')).toBeInTheDocument(); });
# Run Storybook
yarn storybook
# Build Storybook
yarn build-storybook
# Run ESLint
yarn lint
# Run TypeScript type checking
yarn type-check
# Run Prettier
yarn format