This document provides real-world examples of using the Frontend Architect agent for common scenarios.
Provides expert React and Next.js architecture guidance for complex applications. Helps design scalable component systems, implement state management, and optimize performance for production-ready apps.
/plugin marketplace add anton-abyzov/specweave/plugin install sw-frontend@specweaveThis document provides real-world examples of using the Frontend Architect agent for common scenarios.
Building an admin dashboard for an e-commerce platform with inventory management, order tracking, and analytics.
Design a React-based admin dashboard for an e-commerce platform with:
Requirements:
- Real-time order notifications (WebSocket)
- Product inventory management (10,000+ SKUs)
- Analytics charts (sales, revenue, user activity)
- Multi-user role support (admin, manager, viewer)
- Mobile-responsive (tablet and desktop)
Technical Stack:
- Next.js 14 App Router
- TypeScript
- TailwindCSS
- React Query for data fetching
- Zustand for client state
- Recharts for visualization
Performance Targets:
- LCP < 2.5s
- Initial bundle < 300KB
- Smooth 60fps scrolling for large tables
Provide:
1. Component architecture (Atomic Design)
2. Folder structure
3. State management strategy
4. Data fetching patterns
5. Authentication flow
6. Optimization techniques
atoms/
├── Button.tsx
├── Input.tsx
├── Badge.tsx
├── Icon.tsx
├── Avatar.tsx
├── Skeleton.tsx
└── Spinner.tsx
molecules/
├── FormField.tsx
├── SearchBar.tsx
├── Notification.tsx
├── Pagination.tsx
├── StatCard.tsx
├── DataTableHeader.tsx
└── FilterDropdown.tsx
organisms/
├── Sidebar.tsx
├── TopNav.tsx
├── OrderTable.tsx
├── ProductTable.tsx
├── AnalyticsChart.tsx
├── NotificationPanel.tsx
└── UserRoleSelector.tsx
templates/
├── DashboardLayout.tsx
├── AuthLayout.tsx
└── EmptyState.tsx
pages/
├── dashboard/
│ ├── page.tsx (Overview)
│ ├── orders/page.tsx
│ ├── products/page.tsx
│ └── analytics/page.tsx
└── login/page.tsx
src/
├── app/ # Next.js App Router
│ ├── (auth)/
│ │ └── login/
│ │ └── page.tsx
│ ├── (dashboard)/
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ ├── orders/
│ │ │ └── page.tsx
│ │ ├── products/
│ │ │ └── page.tsx
│ │ └── analytics/
│ │ └── page.tsx
│ └── api/
│ └── auth/[...nextauth]/route.ts
│
├── components/ # React components
│ ├── atoms/
│ ├── molecules/
│ ├── organisms/
│ └── templates/
│
├── lib/ # Utilities & configuration
│ ├── api/
│ │ └── client.ts # API client setup
│ ├── hooks/
│ │ ├── useOrders.ts
│ │ ├── useProducts.ts
│ │ ├── useWebSocket.ts
│ │ └── useAuth.ts
│ ├── store/
│ │ └── index.ts # Zustand store
│ └── utils/
│ ├── formatters.ts
│ └── validators.ts
│
├── types/ # TypeScript types
│ ├── order.ts
│ ├── product.ts
│ ├── user.ts
│ └── api.ts
│
└── styles/ # Global styles
└── globals.css
Client State (Zustand):
// lib/store/index.ts
import { create } from 'zustand';
import { devtools, persist } from 'zustand/middleware';
interface DashboardState {
// UI State
sidebarCollapsed: boolean;
theme: 'light' | 'dark';
// User State
user: User | null;
permissions: string[];
// Notifications
notifications: Notification[];
unreadCount: number;
// Actions
toggleSidebar: () => void;
setTheme: (theme: 'light' | 'dark') => void;
addNotification: (notification: Notification) => void;
markAsRead: (id: string) => void;
}
export const useDashboardStore = create<DashboardState>()(
devtools(
persist(
(set) => ({
sidebarCollapsed: false,
theme: 'light',
user: null,
permissions: [],
notifications: [],
unreadCount: 0,
toggleSidebar: () => set((state) => ({
sidebarCollapsed: !state.sidebarCollapsed
})),
setTheme: (theme) => set({ theme }),
addNotification: (notification) => set((state) => ({
notifications: [notification, ...state.notifications],
unreadCount: state.unreadCount + 1,
})),
markAsRead: (id) => set((state) => ({
notifications: state.notifications.map(n =>
n.id === id ? { ...n, read: true } : n
),
unreadCount: Math.max(0, state.unreadCount - 1),
})),
}),
{ name: 'dashboard-store' }
)
)
);
Server State (React Query):
// lib/hooks/useOrders.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient } from '@/lib/api/client';
export function useOrders(filters: OrderFilters) {
return useQuery({
queryKey: ['orders', filters],
queryFn: () => apiClient.getOrders(filters),
staleTime: 30000, // 30 seconds
});
}
export function useUpdateOrderStatus() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (params: { orderId: string; status: string }) =>
apiClient.updateOrderStatus(params.orderId, params.status),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['orders'] });
},
});
}
Server Components (Default):
// app/(dashboard)/orders/page.tsx
import { Suspense } from 'react';
import { OrderTable } from '@/components/organisms/OrderTable';
import { Skeleton } from '@/components/atoms/Skeleton';
export default async function OrdersPage() {
// Fetch in Server Component (no client-side loading state needed)
const initialOrders = await fetch('https://api.example.com/orders', {
next: { revalidate: 60 }, // ISR: revalidate every 60 seconds
}).then(res => res.json());
return (
<div>
<h1>Orders</h1>
<Suspense fallback={<Skeleton />}>
<OrderTable initialData={initialOrders} />
</Suspense>
</div>
);
}
Client Components (Interactive):
// components/organisms/OrderTable.tsx
'use client';
import { useOrders } from '@/lib/hooks/useOrders';
import { useState } from 'react';
export function OrderTable({ initialData }: { initialData: Order[] }) {
const [filters, setFilters] = useState({ status: 'all', page: 1 });
const { data: orders, isLoading } = useOrders(filters, {
initialData, // Use server-fetched data as initial state
refetchInterval: 30000, // Refetch every 30s
});
return (
<div>
{/* Filters, pagination, etc. */}
{isLoading ? <Skeleton /> : <Table data={orders} />}
</div>
);
}
// lib/hooks/useWebSocket.ts
import { useEffect } from 'react';
import { useDashboardStore } from '@/lib/store';
import { useQueryClient } from '@tanstack/react-query';
export function useWebSocket() {
const queryClient = useQueryClient();
const addNotification = useDashboardStore(state => state.addNotification);
useEffect(() => {
const ws = new WebSocket(process.env.NEXT_PUBLIC_WS_URL!);
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
switch (message.type) {
case 'ORDER_CREATED':
addNotification({
id: Date.now().toString(),
type: 'info',
title: 'New Order',
message: `Order #${message.orderId} created`,
timestamp: Date.now(),
});
queryClient.invalidateQueries({ queryKey: ['orders'] });
break;
case 'INVENTORY_LOW':
addNotification({
id: Date.now().toString(),
type: 'warning',
title: 'Low Inventory',
message: `${message.productName} is running low`,
timestamp: Date.now(),
});
break;
}
};
return () => ws.close();
}, [addNotification, queryClient]);
}
// Usage in layout
// app/(dashboard)/layout.tsx
'use client';
import { useWebSocket } from '@/lib/hooks/useWebSocket';
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
useWebSocket(); // Connect to WebSocket on mount
return <div>{children}</div>;
}
Code Splitting:
// app/(dashboard)/analytics/page.tsx
import dynamic from 'next/dynamic';
import { Skeleton } from '@/components/atoms/Skeleton';
// Lazy load heavy chart library
const AnalyticsChart = dynamic(
() => import('@/components/organisms/AnalyticsChart'),
{
loading: () => <Skeleton className="h-96" />,
ssr: false, // Don't render on server (chart library is client-only)
}
);
export default function AnalyticsPage() {
return (
<div>
<h1>Analytics</h1>
<AnalyticsChart />
</div>
);
}
Virtual Scrolling for Large Tables:
// components/organisms/ProductTable.tsx
'use client';
import { useVirtualizer } from '@tanstack/react-virtual';
import { useRef } from 'react';
export function ProductTable({ products }: { products: Product[] }) {
const parentRef = useRef<HTMLDivElement>(null);
const virtualizer = useVirtualizer({
count: products.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 50, // Row height
overscan: 10, // Render 10 extra rows for smooth scrolling
});
return (
<div ref={parentRef} className="h-96 overflow-auto">
<div style={{ height: `${virtualizer.getTotalSize()}px` }}>
{virtualizer.getVirtualItems().map((virtualRow) => (
<div
key={virtualRow.index}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: `${virtualRow.size}px`,
transform: `translateY(${virtualRow.start}px)`,
}}
>
<ProductRow product={products[virtualRow.index]} />
</div>
))}
</div>
</div>
);
}
Image Optimization:
// components/organisms/ProductCard.tsx
import Image from 'next/image';
export function ProductCard({ product }: { product: Product }) {
return (
<div>
<Image
src={product.imageUrl}
alt={product.name}
width={300}
height={300}
placeholder="blur"
blurDataURL={product.thumbnailUrl}
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
</div>
);
}
Building a high-performance marketing website for a SaaS product with SEO optimization and accessibility.
Design a Next.js marketing website for a B2B SaaS platform with:
Requirements:
- 10+ landing pages (home, features, pricing, about, blog)
- SEO optimized (meta tags, structured data, sitemap)
- Accessibility WCAG AA compliant
- Blog with MDX support
- Contact form with Resend integration
- Newsletter signup
- Dark mode support
- i18n support (English, Spanish, German)
Performance Targets:
- Lighthouse score 95+ (all categories)
- LCP < 2.5s
- CLS < 0.1
- 100% accessibility score
Technical Stack:
- Next.js 14 App Router
- TypeScript
- TailwindCSS
- shadcn/ui components
- MDX for blog
- next-intl for i18n
Provide component architecture and implementation examples.
[Detailed architecture with folder structure, SEO setup, i18n configuration, MDX integration, and accessibility patterns]
Building a real-time chat application with WebSocket, typing indicators, and message history.
[Full example with WebSocket setup, optimistic updates, and offline support]
Migrating from Material-UI to a custom design system based on shadcn/ui.
[Step-by-step migration plan with component mapping and codemods]
Optimizing a slow Next.js application (LCP 8s → 2s target).
[Performance audit, bottleneck analysis, optimization implementation]
Setting up a micro-frontend architecture with Module Federation for a large enterprise application.
[Webpack 5 Module Federation setup, shared dependencies, independent deployments]
// Server Component (default in App Router)
export default async function Page() {
const data = await fetchData(); // Server-side fetch
return <ClientComponent initialData={data} />;
}
// Client Component (interactive)
'use client';
export function ClientComponent({ initialData }) {
const [state, setState] = useState(initialData);
// Interactive logic here
}
const mutation = useMutation({
mutationFn: updateTodo,
onMutate: async (newTodo) => {
await queryClient.cancelQueries({ queryKey: ['todos'] });
const previousTodos = queryClient.getQueryData(['todos']);
// Optimistically update UI
queryClient.setQueryData(['todos'], (old) => [...old, newTodo]);
return { previousTodos };
},
onError: (err, newTodo, context) => {
// Rollback on error
queryClient.setQueryData(['todos'], context.previousTodos);
},
});
// Fetch multiple resources in parallel (Server Component)
export default async function Page() {
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments(),
]);
return <Dashboard user={user} posts={posts} comments={comments} />;
}
Use this agent to verify that a Python Agent SDK application is properly configured, follows SDK best practices and documentation recommendations, and is ready for deployment or testing. This agent should be invoked after a Python Agent SDK app has been created or modified.
Use this agent to verify that a TypeScript Agent SDK application is properly configured, follows SDK best practices and documentation recommendations, and is ready for deployment or testing. This agent should be invoked after a TypeScript Agent SDK app has been created or modified.