Next.js Integration
Complete guide to integrating Yeld with your Next.js application.
Quick Start with Next.js
Yeld is built on Next.js and integrates seamlessly with your existing Next.js app.
1
Install Dependencies
Install the required dependencies for your Next.js project:
```bash
npm install @supabase/ssr @supabase/supabase-js viem
npm install frosted-ui @frosted-ui/icons
npm install @web3icons/react lucide-react
```
Or with yarn:
```bash
yarn add @supabase/ssr @supabase/supabase-js viem
yarn add frosted-ui @frosted-ui/icons
yarn add @web3icons/react lucide-react
```2
Configure Environment
Create a `.env.local` file with your configuration:
```env
# Required
EVM_MASTER_MNEMONIC=your_master_mnemonic_here
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
# Optional
YELD_API_KEY=your_api_key
```
**Generate a master mnemonic:**
```bash
openssl rand -hex 32
# Copy the output as your master mnemonic
```3
Set Up Database
Initialize your database schema using Drizzle:
```bash
# Generate migration files
npx drizzle-kit generate
# Push schema to database
npx drizzle-kit push
# Or run migrations
npx drizzle-kit migrate
```
**Database Schema:**
The schema includes tables for users, businesses, wallets, checkout links, and checkout sessions.4
Configure Supabase Client
Create your Supabase client in `@/lib/supabase/client.ts`
```typescript
// lib/supabase/client.ts
import { createBrowserClient } from "@supabase/ssr";
import { supabaseKey, supabaseUrl } from "@/lib/supabase";
export function createSupabaseBrowserClient() {
return createBrowserClient(supabaseUrl, supabaseKey);
}
```
**For server-side usage:**
```typescript
// lib/supabase/server.ts
import { createServerClient } from "@supabase/ssr";
import { cookies } from "next/headers";
export function createSupabaseServerClient() {
const cookieStore = cookies();
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value;
},
set(name: string, value: string, options: any) {
cookieStore.set({ name, value, ...options });
},
remove(name: string, options: any) {
cookieStore.set({
name,
value: "",
...options,
});
},
},
}
);
}
```5
Create a Checkout Button
Add a checkout button component to your page:
```tsx
// components/CheckoutButton.tsx
"use client";
import { useState } from "react";
import { createCheckoutLink } from "@/lib/checkout-links";
import { Button } from "@/components/ui/button";
import { Loader2, CheckCircle2 } from "lucide-react";
export function CheckoutButton({ bizId }: { bizId: string }) {
const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(false);
const [error, setError] = useState<string | null>(null);
async function handleCreateLink() {
setLoading(true);
setError(null);
try {
const result = await createCheckoutLink(bizId, {
planName: "Premium Plan",
plan: "premium",
description: "Monthly premium subscription",
price: "50.00",
billing: "recurring",
initialFee: "",
trial: "7",
stock: "100",
});
if (result.ok) {
setSuccess(true);
} else {
setError(result.error);
}
} catch (err) {
setError("Failed to create checkout link");
} finally {
setLoading(false);
}
}
return (
<div className="flex items-center gap-4">
<Button onClick={handleCreateLink} disabled={loading}>
{loading ? (
<>
<Loader2 className="mr-2 size-4 animate-spin" />
Creating...
</>
) : success ? (
<>
<CheckCircle2 className="mr-2 size-4" />
Created!
</>
) : (
"Create Checkout Link"
)}
</Button>
{error && (
<p className="text-sm text-destructive">{error}</p>
)}
</div>
);
}
```Next.js Configuration
Next Config
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// Enable server actions
experimental: {
serverActions: {
allowedOrigins: ["localhost:3000", "yourdomain.com"],
},
},
};
export default nextConfig;TypeScript Config
// tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}Project Structure
# Recommended project structure
yeld-app/
├── src/
│ ├── app/
│ │ ├── (site)/
│ │ │ ├── docs/
│ │ │ ├── pricing/
│ │ │ └── signup/
│ │ ├── (dashboard)/
│ │ │ └── [bizId]/
│ │ │ └── dashboard/
│ │ └── layout.tsx
│ ├── components/
│ │ ├── ui/
│ │ └── CheckoutButton.tsx
│ ├── lib/
│ │ ├── auth/
│ │ ├── businesses.ts
│ │ ├── checkout-links.ts
│ │ ├── evm.ts
│ │ ├── prices.ts
│ │ └── supabase/
│ ├── db/
│ │ └── schema.ts
│ └── globals.css
├── drizzle/
│ └── schema.ts
├── .env.local
├── drizzle.config.ts
└── package.jsonBest Practices
Use Server Actions
For database operations and sensitive logic, use Next.js server actions (\"use server\") to keep code secure.
Environment Variables
Use \`.env.local\` for local development and platform secrets for production. Never commit secrets to version control.
Use Middleware for Auth
Implement auth checks in Next.js middleware to protect dashboard routes.