#How do I use convex with Next JS API routes when using app directory?

5 messages · Page 1 of 1 (latest)

hearty goblet
#

Please share

  • files to make
  • sample code
rugged dewBOT
#

Hi @hearty goblet. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To use Convex with Next.js API routes in the App Router, you'll need to set up your Convex client and create route handlers that can interact with your Convex backend. Here's how to do it:

Files to Make

  1. app/ConvexClientProvider.tsx - Client component for Convex provider
  2. app/layout.tsx - Root layout with Convex provider
  3. app/api/route.ts - API route handler
  4. convex/tasks.ts - Example Convex function

Sample Code

1. Create a Client Provider Component

First, create a client component that initializes the Convex client:

"use client";

import { ConvexProvider, ConvexReactClient } from "convex/react";
import { ReactNode } from "react";

const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);

export function ConvexClientProvider({ children }: { children: ReactNode }) {
  return <ConvexProvider client={convex}>{children}</ConvexProvider>;
}

2. Set Up Your Root Layout

In your root layout, wrap your application with the Convex provider:

import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { ConvexClientProvider } from "./ConvexClientProvider";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        <ConvexClientProvider>{children}</ConvexClientProvider>
      </body>
    </html>
  );
}

3. Create an API Route Handler

#

Create a route handler that uses Convex functions:

import { NextResponse } from "next/server";
// Hack for TypeScript before 5.2
const Response = NextResponse;

import { api } from "@/convex/_generated/api";
import { fetchMutation } from "convex/nextjs";

export async function POST(request: Request) {
  const args = await request.json();
  await fetchMutation(api.tasks.create, { text: args.text });
  return Response.json({ success: true });
}

4. Create a Convex Function

Create a Convex function that your API route will call:

import { mutation } from "./_generated/server";
import { v } from "convex/values";

export const create = mutation({
  args: { text: v.string() },
  handler: async (ctx, args) => {
    return await ctx.db.insert("tasks", {
      text: args.text,
      isCompleted: false,
    });
  },
});

Using Server Actions

You can also use Convex with Server Actions in Next.js. Here's an example:

import { api } from "@/convex/_generated/api";
import { fetchMutation, fetchQuery } from "convex/nextjs";
import { revalidatePath } from "next/cache";

export default async function PureServerPage() {
  const tasks = await fetchQuery(api.tasks.list, { list: "default" });
  
  async function createTask(formData: FormData) {
    "use server";

    await fetchMutation(api.tasks.create, {
      text: formData.get("text") as string,
    });
    revalidatePath("/example");
  }
  
  // render tasks and task creation form
  return <form action={createTask}>...</form>;
}

For authenticated requests, you'll need to pass a JWT token to the Convex functions:

import { preloadQuery } from "convex/nextjs";
import { api } from "@/convex/_generated/api";
#

export async function TasksWrapper() {
const token = await getAuthToken();
const preloadedTasks = await preloadQuery(
api.tasks.list,
{ list: "default" },
{ token },
);
return <Tasks preloadedTasks={preloadedTasks} />;
}


The implementation of `getAuthToken` depends on your authentication provider (Clerk, Auth0, etc.).

[Next.js Server Rendering](<https://docs.convex.dev/client/react/nextjs/server-rendering#server-actions-and-route-handlers>) provides more details on using Convex with Server Actions and Route Handlers.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------