Next.js Quickstart
Learn how to query data from Convex in a Next.js app using the App Router and
Alternatively see the Pages Router version of this quickstart.
- Create a React app
Create a Next.js app using the
npx create-next-app
command.Choose the default option for every prompt (hit Enter).
npx create-next-app@latest my-app
- Install the Convex client and server library
To get started, install the
convex
package which provides a convenient interface for working with Convex from a React app.Navigate to your app and install
convex
.cd my-app && npm install convex
- Setup a Convex dev deployment
Next, run
npx convex dev
. This will prompt you to log in with GitHub, create a project, and save your production and deployment URLs.It will also create a
convex/
folder for you to write your backend API functions in. Thedev
command will then continue running to sync your functions with your dev deployment in the cloud.npx convex dev
- Create sample data for your database
In a new terminal window, create a
sampleData.jsonl
file with some sample data.sampleData.jsonl{"text": "Buy groceries", "isCompleted": true}
{"text": "Go for a swim", "isCompleted": true}
{"text": "Integrate Convex", "isCompleted": false} - Add the sample data to your database
Now that your project is ready, add a
tasks
table with the sample data into your Convex database with theimport
command.npx convex import tasks sampleData.jsonl
- Expose a database query
Add a new file
tasks.ts
in theconvex/
folder with a query function that loads the data.Exporting a query function from this file declares an API function named after the file and the export name,
api.tasks.get
.convex/tasks.tsTSimport { query } from "./_generated/server";
export const get = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("tasks").collect();
},
}); - Create a client component for the Convex provider
Add a new file
ConvexClientProvider.tsx
in theapp/
folder. Include the"use client";
directive, create aConvexReactClient
and a component that wraps its children in aConvexProvider
.app/ConvexClientProvider.tsxTS"use client";
import { ReactNode } from "react";
import { ConvexProvider, ConvexReactClient } from "convex/react";
const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
export default function ConvexClientProvider({
children,
}: {
children: ReactNode;
}) {
return <ConvexProvider client={convex}>{children}</ConvexProvider>;
} - Wire up the ConvexClientProvider
In
app/layout.tsx
, wrap the children of thebody
element with theConvexClientProvider
.app/layout.tsxTSimport "./globals.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import ConvexClientProvider from "./ConvexClientProvider";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>
<ConvexClientProvider>{children}</ConvexClientProvider>
</body>
</html>
);
} - Display the data in your app
In
app/page.tsx
, use theuseQuery
hook to fetch from yourapi.tasks.get
API function.app/page.tsxTS"use client";
import { useQuery } from "convex/react";
import { api } from "../convex/_generated/api";
export default function Home() {
const tasks = useQuery(api.tasks.get);
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
{tasks?.map(({ _id, text }) => (
<div key={_id}>{text}</div>
))}
</main>
);
} - Start the app
Start the app, open http://localhost:3000 in a browser, and see the list of tasks.
npm run dev