Back to Docs

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.json

Best 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.

React Integration