I'm in love building websites, whether it's front-end work or back-end. However, sometimes you've just got an idea that you want to scaffold right away without spending much time on API and database. Luckily, thanks to Web Dev Cody channel, I found out about Convex, a tool that does all of API-database tedious configuration for you, and moreover, giving you a lot of additional complex features you might use, such as Web Sockets that update data dynamically on the layout.
Create a NextJS app using the following command
npx create-next-app@latest nextjs-convex-app
Navigate to your app
cd nextjs-convex-app
and install convex package that provides a convenient interface for working with Convex from NextJS app
npm install convex
Remember that all the steps above I take straight from the Convex docs.
Then, run npx convex dev
command to get convex rolling. It'll prompt you to log in with Github, create a project, and save a production and deployment URLs.
npx convex dev
You got a NextJS and Convex in place, now it's time to start working with them both.
Populate Convex database with sample data by creating a file sampleData.jsonl
at the root of the project and adding there the next data
{"text": "Beat Witcher 3", "isCompleted": true}
{"text": "Meditate by imagining yourself in the inn near the Novigrad", "isCompleted": false}
{"text": "Put yourself together", "isCompleted": false}
Add this data to Convex database
npx convex import --table tasks sampleData.jsonl
Inside of convex/
folder create tasks.ts
file that will be a store for query functions. Write and export GET query
// convex/tasks.ts
import { query } from "./_generated/server";
export const get = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("tasks").collect();
},
});
Add a new file ConvexClientProvider.tsx
in the /app
folder. This must be a client component so place use client
at the top of the file and copy paste the following code there as well
// app/ConvexClientProdiver.tsx
"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>;
}
Open layout.tsx
file inside of /app
folder, import created ConvexProvider and wrap up children with it
// app/layout.tsx
import "./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>
);
}
To use queries exported from convex/tasks.ts
, Convex gives a very convenient function useQuery
that takes a query as a parameter and then does all complicated stuff for you, you are left only to display the data
// app/page.tsx
"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>
);
}
Run NextJS app
npm run dev
you'll see the data displayed. Go to https://dashboard.convex.dev, choose your project, and then change some data there and return to localhost - data was changed dynamically!
Now with Convex, you've got a bunch of cool projects to try out. It takes care of all the tricky stuff with APIs and databases, so you can just focus on bringing your ideas to life. Enjoy coding without the hassle!