Streamlining Provider Integrations in Dyad
At Dyad, we aim to provide a frictionless setup experience for our users. As we expand our support for various LLM providers, we recognized the need to standardize how users select and configure their services during onboarding. Previously, adding a new provider meant manually building out UI components, leading to inconsistency. We recently refactored this flow by introducing a reusable provider card system.
The Problem: Scaling Provider Onboarding
When we only supported one or two providers, hardcoding the setup UI was manageable. However, as we added more, the SetupBanner component became cluttered and difficult to maintain. Adding a new provider required duplicating styles, logic, and event tracking, which is a recipe for technical debt.
The Solution: Component-Driven Configuration
To address this, we extracted the provider display into a SetupProviderCard component. This allows us to pass configuration props for each provider, ensuring a consistent visual and functional contract across the board.
interface ProviderCardProps {
name: string;
onSelect: () => void;
icon: React.ReactNode;
}
const SetupProviderCard: React.FC<ProviderCardProps> = ({ name, onSelect, icon }) => (
<button onClick={onSelect} className="provider-card">
{icon}
<span>{name}</span>
</button>
);
This simple abstraction ensures that whenever we add a new integration, such as our recent support for OpenRouter, we simply instantiate a new card rather than rewriting the layout logic.
Ensuring Reliability with E2E Testing
With the UI streamlined, we needed to ensure the navigation flow remained intact. We implemented a new suite of tests using Playwright to verify that selecting a provider correctly routes the user to the appropriate settings panel and triggers the necessary analytics events.
test('navigates to provider settings', async ({ page }) => {
await page.goto('/setup');
await page.click('text=OpenRouter');
await expect(page).toHaveURL(/.*\/settings\/openrouter/);
});
Key Takeaways
- Standardization: By creating reusable components like
SetupProviderCard, we reduced boilerplate and ensured a consistent UX. - Testing at Scale: Introducing E2E tests for the onboarding flow allows us to iterate on new provider integrations with confidence.
- Developer Experience: Centralizing the logic makes it easier for the team to manage provider-specific configuration flags, like our new
showSetupScreentest toggle.
By treating the onboarding setup as a scalable component architecture, we've made the addition of future services a trivial task.
Generated with Gitvlg.com