# ๐ฅ Les Crรชpes de Maรฎtres
A beautiful demo showcasing **[json-render](https://github.com/vercel-labs/json-render)** with French chef crรชpe recipes. Features recipes from legendary chefs like Auguste Escoffier, Olivier Roellinger, Pierre Hermรฉ, and Joรซl Robuchon.
## ๐ฏ What is json-render?
**json-render** is a library from Vercel Labs that enables AI-generated UIs with guardrailed components. It provides:
- **Guardrailed** โ AI can only use components in your catalog
- **Predictable** โ JSON output matches your schema, every time
- **Fast** โ Stream and render progressively as the model responds
This demo uses json-render's `Renderer` component with a type-safe catalog to render recipe specs as React components.
## โจ How It Works
1. **Define Component Catalog** (`lib/catalog.ts`):
```typescript
export const catalog = defineCatalog(schema, {
components: {
RecipeHeader: {
props: z.object({
title: z.string(),
chef: z.string(),
// ...
}),
description: "Header with recipe info"
},
// ...
}
});
```
2. **Map to React Components** (`lib/registry.tsx`):
```typescript
export const { registry } = defineRegistry(catalog, {
components: {
RecipeHeader: ({ props }) => (
{props.title}
{/* ... */}
),
// ...
}
});
```
3. **Create JSON Specs** (`lib/recipes.ts`):
```typescript
const recipe = {
root: "root",
elements: {
root: {
type: "RecipeCard",
props: { title: "Crรชpes Suzette", /* ... */ },
children: ["chef", "header", "ingredients", /* ... */]
},
chef: {
type: "ChefInfo",
props: { name: "Auguste Escoffier", /* ... */ }
},
// ...
}
};
```
4. **Render with json-render** (`app/page.tsx`):
```typescript
```
**Result**: AI-generated JSON specs become beautiful, type-safe React UIs!
## ๐ Quick Start (Local Development)
```bash
# Install dependencies
npm install
# Run development server
npm run dev
# Open http://localhost:3000
```
## ๐ณ Docker Build
```bash
# Build the image
docker build -t crepes-demo:latest .
# Run locally
docker run -p 3000:3000 crepes-demo:latest
```
## โธ๏ธ Kubernetes Deployment with Flux
### Prerequisites
- Kubernetes cluster with Flux installed
- Container registry (Docker Hub, GitHub Container Registry, etc.)
- Domain configured with Cloudflare
- Ingress controller (nginx, traefik, etc.)
- cert-manager for TLS certificates
- external-dns for automatic DNS records (optional)
### Step 1: Build and Push Image
```bash
# Tag your image
docker tag crepes-demo:latest YOUR_REGISTRY/crepes-demo:latest
# Push to registry
docker push YOUR_REGISTRY/crepes-demo:latest
```
### Step 2: Update Configuration
**k8s/deployment.yaml:**
- Update `image:` with your registry URL
**k8s/ingress.yaml:**
- Update all instances of `crepes.yourdomain.com` with your actual domain
- Adjust `ingressClassName` if not using nginx
- Verify cert-manager issuer name
**flux/gitrepository.yaml:**
- Update Git repository URL with your fork
### Step 3: Use the Deploy Script
```bash
cd /home/openclaw/.openclaw/workspace/crepes-demo
# Set your configuration
export REGISTRY="ghcr.io/YOUR_USERNAME"
export DOMAIN="crepes.yourdomain.com"
# Run deployment script
./deploy.sh $REGISTRY $DOMAIN
```
### Step 4: Push to Git
```bash
# Initialize git repository
git init
git add .
git commit -m "Initial commit: json-render crรชpes demo"
# Push to your GitHub repository
git remote add origin https://github.com/YOUR_USERNAME/crepes-demo.git
git push -u origin main
```
### Step 5: Deploy Flux Resources
```bash
# Apply Flux GitRepository and Kustomization
kubectl apply -f flux/gitrepository.yaml
kubectl apply -f flux/kustomization.yaml
# Watch deployment
kubectl get kustomizations -n flux-system -w
```
### Step 6: Verify Deployment
```bash
# Check pods
kubectl get pods -l app=crepes-demo
# Check service
kubectl get svc crepes-demo
# Check ingress
kubectl get ingress crepes-demo
# Check Flux sync status
flux get kustomizations
```
### Step 7: Configure Cloudflare
If using external-dns with Cloudflare:
1. DNS records should be created automatically
2. Verify in Cloudflare dashboard
3. Ensure SSL/TLS mode is "Full (strict)" or "Full"
If configuring manually:
1. Create an A or CNAME record pointing to your ingress IP/hostname
2. Enable Cloudflare proxy (orange cloud) for DDoS protection
3. Configure SSL/TLS settings
## ๐ Continuous Deployment
Flux will automatically:
- Monitor your Git repository every 1 minute
- Apply changes to the cluster
- Check deployment health
- Rollback on failures
To update the app:
```bash
# Make changes
git add .
git commit -m "Update recipe"
git push
# Flux will sync automatically, or force sync:
flux reconcile kustomization crepes-demo
```
## ๐จ Customization
### Adding New Recipes
1. Define your recipe spec in `lib/recipes.ts`:
```typescript
{
root: "root",
elements: {
root: {
type: "RecipeCard",
props: { title: "My Recipe", /* ... */ },
children: ["chef", "header", /* ... */]
},
// ... more elements
}
}
```
2. The spec will be automatically rendered using the existing component catalog!
### Adding New Components
1. Update component schema in `lib/catalog.ts`:
```typescript
MyNewComponent: {
props: z.object({
myProp: z.string(),
}),
description: "My new component"
}
```
2. Add React implementation in `lib/registry.tsx`:
```typescript
MyNewComponent: ({ props }) => (
{props.myProp}
)
```
3. Use in recipe specs with `type: "MyNewComponent"`
### Styling
The app uses Tailwind CSS. Modify component styles in `lib/registry.tsx` or adjust the theme in `tailwind.config.ts`.
## ๐ Project Structure
```
crepes-demo/
โโโ app/
โ โโโ page.tsx # Main page with Renderer
โ โโโ layout.tsx # Root layout
โ โโโ globals.css # Global styles
โโโ lib/
โ โโโ catalog.ts # json-render component catalog
โ โโโ registry.tsx # React component implementations + Provider
โ โโโ recipes.ts # Recipe JSON specs
โโโ k8s/
โ โโโ deployment.yaml # Kubernetes Deployment
โ โโโ service.yaml # Kubernetes Service
โ โโโ ingress.yaml # Kubernetes Ingress (Cloudflare)
โ โโโ kustomization.yaml # Kustomize config
โโโ flux/
โ โโโ gitrepository.yaml # Flux GitRepository
โ โโโ kustomization.yaml # Flux Kustomization
โโโ .github/workflows/
โ โโโ deploy.yml # GitHub Actions CI/CD
โโโ Dockerfile # Multi-stage Docker build
โโโ deploy.sh # Automated deployment script
โโโ README.md # Full documentation (this file)
โโโ QUICKSTART.md # Quick deployment guide
```
## ๐ง Troubleshooting
### Pods not starting
```bash
kubectl describe pod -l app=crepes-demo
kubectl logs -l app=crepes-demo
```
### Flux not syncing
```bash
flux logs
flux get sources git
flux get kustomizations
```
### Certificate issues
```bash
kubectl describe certificate crepes-demo-tls
kubectl describe certificaterequest
kubectl logs -n cert-manager -l app=cert-manager
```
### DNS not resolving
```bash
# Check external-dns logs
kubectl logs -n external-dns -l app=external-dns
# Verify ingress has external IP
kubectl get ingress crepes-demo
```
## ๐ Architecture
```
User Request
โ
Cloudflare (CDN, DDoS protection, SSL)
โ
Ingress Controller (nginx)
โ
Kubernetes Service
โ
Deployment (2 replicas)
โ
Next.js App (json-render Renderer)
```
## ๐ Learning json-render
This demo shows the core concepts:
1. **Catalog Definition**: Define allowed components with typed props (Zod schemas)
2. **Registry**: Map component names to React implementations
3. **Spec Format**: JSON tree structure with `root` + `elements`
4. **Renderer**: Takes spec + registry, outputs React components
5. **Provider**: Wraps Renderer with required contexts (Action, Data, Visibility)
**In production with AI**:
- User types: "Show me a recipe for chocolate chip cookies"
- AI generates a JSON spec using your catalog components
- json-render's `Renderer` turns it into React instantly
- **Safe**: AI can't inject arbitrary code, only use your components
## ๐ Additional Resources
- [json-render GitHub](https://github.com/vercel-labs/json-render) - Official repository
- [Flux documentation](https://fluxcd.io/docs/) - GitOps toolkit
- [Next.js deployment](https://nextjs.org/docs/deployment) - Deployment guides
- [Cloudflare Pages/Workers](https://developers.cloudflare.com/) - Edge deployment
## ๐ด Recipe Credits
Recipes inspired by the legendary techniques of:
- **Auguste Escoffier** - Father of modern French cuisine (Crรชpes Suzette)
- **Olivier Roellinger** - Three-Michelin-starred Breton chef (Buckwheat Galettes)
- **Pierre Hermรฉ** - "Picasso of Pastry" (Salted Caramel Crรชpes)
- **Joรซl Robuchon** - Most Michelin-starred chef in history (Crรชpes Parmentier)
## ๐ License
MIT License - Feel free to use this demo for your own projects!
---
**Built with โค๏ธ using json-render. Bon Appรฉtit! ๐ซ๐ท**