Skip to main content

Extending the Template

Learn where and how to add custom functionality to the Vertical Template.

Extension Point Map

Vertical-Template/
├── src/
│ ├── app/
│ │ ├── api/ 🔌 API Routes
│ │ │ └── [your-route]/ Add new API endpoints
│ │ │ └── route.ts
│ │ │
│ │ └── (presentation)/ 📄 Pages
│ │ └── [your-page]/ Add new pages
│ │ └── page.tsx
│ │
│ ├── eai.config/
│ │ └── tenants/ 🔧 Tenant Configs
│ │ └── [tenant].config.ts Add new tenants
│ │
│ └── components/ 🎨 Components
│ └── [your-component].tsx Add custom components

├── packages/client/
│ └── src/
│ ├── components/ 📦 Shared Components
│ │ └── [component]/ Add to client package
│ │
│ └── hooks/ 🪝 Custom Hooks
│ └── use[Hook].ts Add custom hooks

└── .claude/skills/ 🤖 AI Skills
└── [skill]/ Add Agent Skills
└── SKILL.md

Quick Reference

I want to...LocationGuide
Add a new pagesrc/app/(presentation)/[page]/page.tsxAdding Pages
Add an API routesrc/app/api/[route]/route.tsAdding API Routes
Create a componentsrc/components/[component].tsxCustom Components
Add a tenantsrc/eai.config/tenants/[tenant].config.tsFirst Vertical
Use Public APIsrc/app/api/eai/public/...Public API Access

Extension Patterns

1. Config-First Approach

New features should integrate with the config-driven system:

// 1. Create your component
export function MyWidget({ data, onAction }: Props) {
return <div>...</div>;
}

// 2. Register in ComponentRegistry
registry.set('MyWidget', MyWidget);

// 3. Add to tenant config
{
component: 'MyWidget',
priority: 1,
storeBindings: [
{ prop: 'data', storePath: 'mySlice.data' }
],
}

2. Protected Routes

Use middleware for authenticated pages:

// src/middleware.ts
export const config = {
matcher: [
'/dashboard/:path*',
'/api/protected/:path*',
],
};

3. Store Integration

New features should use the Zustand store:

// Read state
const value = useStoreValue('mySlice.property');

// Write state
const setStore = useSetStore();
setStore('mySlice.property', newValue, 'MyComponent');

4. API Proxy Pattern

Backend calls go through the BFF proxy:

// Client-side fetch
const data = await fetch('/api/eai/v3/endpoint', {
credentials: 'include',
});

// Token injected server-side by proxy route

Common Extensions

Adding a Dashboard Widget

  1. Create component in src/components/
  2. Register in ComponentRegistry
  3. Add to tenant config with storeBindings
  4. Add store slice if needed

Adding a Settings Page

  1. Create page at src/app/(presentation)/settings/page.tsx
  2. Add protected route to middleware
  3. Create settings form component
  4. Persist settings to store with persist: true

Adding an API Integration

  1. Create API route at src/app/api/[integration]/route.ts
  2. Handle authentication (session or client credentials)
  3. Create client-side hook to consume API
  4. Add to component via store or direct fetch

Code-Adjacent Documentation

Each major directory has a README with local conventions:

  • src/eai.config/README.md - How to add tenants
  • src/components/README.md - Component conventions
  • src/app/api/README.md - API route patterns

Next Steps

CLI & Platform