### Start the Project with Bun Source: https://stack.convex.dev/user-authentication-with-clerk-and-convex This command starts the development server for the project. It requires `bun` to be installed and the project dependencies to be already installed. ```bash bun start ``` -------------------------------- ### Setup Self-Hosted Backend with Docker Compose Source: https://stack.convex.dev/self-hosted-develop-and-deploy This snippet demonstrates how to download the `docker-compose.yml` file, pull the necessary Docker images, and start the self-hosted Convex backend containers. It's the recommended method for local development. ```bash npx degit get-convex/convex-backend/self-hosted/docker/docker-compose.yml docker-compose.yml docker compose pull docker compose up ``` -------------------------------- ### Setup: Clone Repository and Install Dependencies Source: https://stack.convex.dev/tanstack-real-time-github-npm-stat-counter Commands to clone the tutorial repository and install project dependencies using npm. This is the initial setup step for the tutorial. ```bash git clone https://github.com/erquhart/convex-oss-stats-tutorial npm install ``` -------------------------------- ### Install Project Packages with Bun Source: https://stack.convex.dev/user-authentication-with-clerk-and-convex Installs all necessary project dependencies. The guide recommends using `bun` for faster installation, but `npm` or `yarn` can also be used. Ensure your chosen package manager is installed. ```bash bun install ``` -------------------------------- ### Install convex-helpers Dependency Source: https://stack.convex.dev/nextauth-adapter Installs the `convex-helpers` package, which is a dependency for the Convex adapter code. This command should be run in your project's terminal. ```bash npm install convex-helpers ``` -------------------------------- ### Install and Initialize Convex CLI Source: https://stack.convex.dev/add-a-collaborative-document-editor-to-your-app Installs the Convex package and starts the development server. This command is used to set up the Convex backend for your project, creating a `convex/` directory for backend code and schema definitions. ```bash 1npm i convex@latest 2npx convex dev --tail-logs 3 ``` -------------------------------- ### Install Dependencies and Run Dev Server Source: https://stack.convex.dev/full-stack-chatgpt-app These commands are used after creating a new Vite React project. 'npm install' downloads the necessary project dependencies, and 'npm run dev' starts the local development server to preview the application. ```bash npm install npm run dev ``` -------------------------------- ### Configure npm Script for Development and Seeding Source: https://stack.convex.dev/seeding-data-for-preview-deployments Set up a package.json script to automatically start the Convex development server and run the data seeding initialization. This streamlines the development process by combining app startup and data setup into a single command. ```json { "scripts": { "dev": "npm run seed && npm run start-dev", "seed": "npx convex dev --run init", "start-dev": "npx convex dev" } } ``` -------------------------------- ### Setting up game state with test-only mutations Source: https://stack.convex.dev/testing-with-local-oss-backend Illustrates using test-only mutations to set up complex initial states for testing. This example shows how to create a chess game with a specific PGN, allowing tests to start from an arbitrary point in the game. ```typescript // Two moves before the end of the game const gameAlmostFinishedPgn = "1. Nf3 Nf6 2. d4 Nc6 3. e4 Nxe4" /* ... */ const gameId = await t.mutation(api.testing.setupGame, { player1: sarahId, player2: leeId, pgn: gameAlmostFinishedPgn, finished: false, }); ``` -------------------------------- ### Passing Session to Convex Client in App Router Source: https://stack.convex.dev/nextauth-adapter This example demonstrates how to pass the user's session object from the server to the client component in Next.js App Router. The `auth` function from `@/auth` is used to get the session, which is then passed to the `ConvexClientProvider`. ```tsx import ConvexClientProvider from "@/app/ConvexClientProvider"; import { auth } from "@/auth"; import { ReactNode } from "react"; export default async function LoggedInLayout({ children, }: { children: ReactNode; }) { const session = await auth(); return ( <> {children} ); } function SignOut() {/*...*/} ``` -------------------------------- ### Install and Initialize Convex Source: https://stack.convex.dev/user-authentication-with-clerk-and-convex Installs the Convex package and initializes a new Convex project. You will be prompted to enter a project name. This command sets up the backend infrastructure for your application. ```bash bun install convex && npx convex dev ``` -------------------------------- ### Start Local Convex Backend Binary Source: https://stack.convex.dev/developing-with-the-oss-backend This command starts the local Convex backend. Ensure you have downloaded the correct binary for your system. The backend will listen on a specific HTTP address, indicated by a log message. ```bash ./convex-local-backend ``` -------------------------------- ### Run `just convex dev` with `Justfile` Source: https://stack.convex.dev/developing-with-the-oss-backend After downloading the `Justfile` and installing `just`, this command runs the Convex development server using the configurations defined in the `Justfile`. This approach is a convenience over directly using `npx convex dev`. ```bash cd convex-chess npm i just convex dev ``` -------------------------------- ### Passing Session to Convex Client in Pages Router Source: https://stack.convex.dev/nextauth-adapter This example illustrates how to retrieve the user session on the server and pass it to the `ConvexClientProvider` in Next.js Pages Router. It utilizes `getServerSideProps` to fetch the session before the page is rendered. ```tsx import ConvexClientProvider from "@/app/ConvexClientProvider"; import { auth } from "@/auth"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { api } from "@/convex/_generated/api"; import { useMutation, useQuery } from "convex/react"; import { GetServerSideProps, InferGetServerSidePropsType } from "next"; import { Session } from "next-auth"; export const getServerSideProps = (async (ctx) => { const session = await auth(ctx); return { props: { session, }, }; }) satisfies GetServerSideProps<{ session: Session | null }>; export default function Page({ ssession, }: InferGetServerSidePropsType) { return ( ); } ``` -------------------------------- ### NextAuth.js Configuration with ConvexAdapter (TypeScript) Source: https://stack.convex.dev/nextauth-adapter Example configuration for NextAuth.js using the ConvexAdapter. This code snippet shows how to import and use the adapter within the NextAuth initialization, setting up providers (omitted here for brevity) and defining handlers for authentication. ```typescript import NextAuth from "next-auth" import { ConvexAdapter } from "@/app/ConvexAdapter"; export const { handlers, auth, signIn, signOut } = NextAuth({ providers: [], adapter: ConvexAdapter, }) ``` -------------------------------- ### Get User by Email (Convex) Source: https://stack.convex.dev/nextauth-adapter Fetches a user record using their email address. It queries the 'users' table with an index on the 'email' field. Returns the unique user if found, otherwise null. This is a common utility for user identification. ```typescript export const getUserByEmail = adapterQuery({ args: { email: v.string() }, handler: async (ctx, { email }) => { return await ctx.db .query("users") .withIndex("email", (q) => q.eq("email", email)) .unique(); }, }); ``` -------------------------------- ### Setup: Configure Convex Project Source: https://stack.convex.dev/tanstack-real-time-github-npm-stat-counter Command to initialize and configure a new Convex project. This sets up the backend environment for the tutorial. ```bash npx convex dev --configure new ``` -------------------------------- ### Install Rust, NVM, and Convex Backend Dependencies Source: https://stack.convex.dev/building-the-oss-backend This comprehensive script installs necessary tools like Rust (via rustup), Node Version Manager (NVM), and then navigates into the cloned repository to install project-specific dependencies using `cargo install just`, `nvm use`, `npm install`, and `just rush install`. This prepares the environment for compiling the Convex backend. ```bash # Install rust curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Install NVM curl -o- https://raw.githubusercontent.com/nvm/nvm/v0.39.7/install.sh | bash # Open a new shell, and install Convex dependencies cd convex-backend # Install just build tool # Note: This might require a specific Rust toolchain version or compiler # Ensure you have a compatible C++ compiler installed if needed by just # For example, on Debian/Ubuntu: sudo apt-get install build-essential # On macOS with Homebrew: brew install pkg-config # On Windows, consider using MSYS2 or WSL cargo install just # Use the appropriate Node.js version managed by NVM nvm use # Install JavaScript dependencies for the scripts directory npm install --prefix scripts # Install project-specific dependencies using Rush (a monorepo tool) just rush install ``` -------------------------------- ### Get User by Account (Convex) Source: https://stack.convex.dev/nextauth-adapter Retrieves a user record based on their provider and provider account ID. It queries the 'accounts' table using a specific index. Returns null if the account is not found. This function is part of the data access layer and uses Convex's query capabilities. ```typescript export const getUserByAccount = adapterQuery({ args: { provider: v.string(), providerAccountId: v.string() }, handler: async (ctx, { provider, providerAccountId }) => { const account = await ctx.db .query("accounts") .withIndex("providerAndAccountId", (q) => q.eq("provider", provider).eq("providerAccountId", providerAccountId), ) .unique(); if (account === null) { return null; } return await ctx.db.get(account.userId); }, }); ``` -------------------------------- ### Compile and Run Convex Local Backend Source: https://stack.convex.dev/building-the-oss-backend This command compiles and starts the local Convex backend. The compilation process can be resource-intensive and time-consuming. Once running, it listens on `http://0.0.0.0:3210`. ```bash just run-local-backend ``` -------------------------------- ### Install and Initialize Convex Source: https://stack.convex.dev/full-stack-chatgpt-app Commands to install the Convex package and initialize a Convex development environment. This process might prompt for login and account creation, and saves deployment URLs to environment files. ```bash npm install convex npx convex dev ``` -------------------------------- ### List Authenticators by User ID (Convex) Source: https://stack.convex.dev/nextauth-adapter Retrieves all authenticator records associated with a given user ID. It queries the 'authenticators' table using an index on 'userId'. This is useful for managing multi-factor authentication setups. ```typescript export const listAuthenticatorsByUserId = adapterQuery({ args: { userId: v.id("users") }, handler: async (ctx, { userId }) => { return await ctx.db .query("authenticators") .withIndex("userId", (q) => q.eq("userId", userId)) .collect(); }, }); ``` -------------------------------- ### Convex React Client Authentication Setup with NextAuth.js Source: https://stack.convex.dev/nextauth-adapter This snippet shows how to replace the default ConvexProvider with ConvexProviderWithAuth in a React application. It integrates with NextAuth.js to manage user sessions and provide authentication tokens to Convex. Ensure NEXT_PUBLIC_CONVEX_URL is set in your environment variables. ```tsx "use client"; import { ConvexProviderWithAuth, ConvexReactClient } from "convex/react"; import { SessionProvider, useSession } from "next-auth/react"; import { Session } from "next-auth"; import { ReactNode, useMemo } from "react"; const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!); export default function ConvexClientProvider({ children, session, }: { // eslint-disable-next-line @typescript-eslint/no-explicit-any children: ReactNode; session: Session | null; }) { return ( {children} ); } function useAuth() { const { data: session, update } = useSession(); const convexToken = convexTokenFromSession(session); return useMemo( () => ({ isLoading: false, isAuthenticated: session !== null, fetchAccessToken: async ({ forceRefreshToken, }: { // eslint-disable-next-line @typescript-eslint/no-explicit-any forceRefreshToken: boolean; }) => { if (forceRefreshToken) { const session = await update(); return convexTokenFromSession(session); } return convexToken; }, }), // We only care about the user changes, and don't want to // bust the memo when we fetch a new token. // eslint-disable-next-line react-hooks/exhaustive-deps [JSON.stringify(session?.user)], ); } function convexTokenFromSession(session: Session | null): string | null { return session?.convexToken ?? null; } ``` -------------------------------- ### TypeScript: Get Button Element for Event Handling Source: https://stack.convex.dev/event-driven-programming This code snippet demonstrates how to get a reference to an HTML button element using its ID. This element will serve as the event source in an event-driven programming scenario. It uses `document.getElementById` and type casting to ensure it's treated as an HTMLButtonElement. ```TypeScript const button = document.getElementById('fetchButton') as HTMLButtonElement; ``` -------------------------------- ### Run `convex dev` with Local Backend Configuration Source: https://stack.convex.dev/developing-with-the-oss-backend This command initiates the Convex development server, pointing it to the locally running backend. It requires the admin key and the URL of the local backend. The provided admin key is a default for the OSS backend and can be safely shared. ```bash npx convex dev \ --admin-key 0135d8598650f8f5cb0f30c34ec2e2bb62793bc28717c8eb6fb577996d50be5f4281b59181095065c5d0f86a2c31ddbe9b597ec62b47ded69782cd \ --url "http://127.0.0.1:3210" ``` -------------------------------- ### GET /listMessages/:userId Source: https://stack.convex.dev/hono-with-convex An example of a dynamic route using Hono to fetch messages for a specific user ID, demonstrating parameter extraction and Convex query execution. ```APIDOC ## GET /listMessages/:userId ### Description This endpoint fetches messages for a specific user identified by `userId` in the URL. It extracts the `userId` parameter, runs a Convex query to get messages by that author, and returns the messages as pretty-printed JSON. ### Method GET ### Endpoint `/listMessages/:userId` ### Parameters #### Path Parameters - **userId** (string) - Required - The ID of the user whose messages to retrieve. Expected to be numeric. #### Query Parameters None #### Request Body None ### Request Example ```bash $ curl https://your-convex-site.convex.site/listMessages/123 ``` ### Response #### Success Response (200) - **Array of message objects** (object[]) - A list of message objects, each containing `_creationTime`, `_id`, `author`, and `body`. #### Response Example ```json [ { "_creationTime": 1677798437141.091, "_id": { "$id": "messages|lqMHm5kDS9m6fBsSnx5L2g" }, "author": "User 123", "body": "Hello world" } ] ``` ``` -------------------------------- ### Add Secret to Arguments (TypeScript) Source: https://stack.convex.dev/nextauth-adapter A utility function that adds the Convex authentication secret to an arguments object. This is typically used before passing arguments to a Convex function. ```typescript function addSecret(args: Record) { return { ...args, secret: process.env.CONVEX_AUTH_ADAPTER_SECRET! }; } ``` -------------------------------- ### Create New Convex App with Prompts Source: https://stack.convex.dev/npm-create-convex Initiates the creation of a new Convex application by running `npm create convex@latest`. This command installs the `create-convex` tool and prompts the user to choose a frontend client (e.g., React/Vite) and an authentication solution (e.g., Clerk). It then sets up the project with the selected configurations. ```bash 1% npm create convex@latest 2Need to install the following packages: 3create-convex@0.0.5 4Ok to proceed? (y) y 5✔ Project name: … my-app 6✔ Choose a client: › React (Vite) 7✔ Choose user authentication solution: › Clerk 8 9Setting up... 10 11added 454 packages in 9s 12 13✔ Done. Now run: 14 15 cd my-app 16 npm run dev 17 ``` -------------------------------- ### Download `Justfile` for Convex Commands Source: https://stack.convex.dev/developing-with-the-oss-backend This command downloads the `Justfile` from the Convex backend repository. The `Justfile` simplifies running Convex CLI commands by pre-configuring the local backend URL and admin key. ```bash curl -O https://raw.githubusercontent.com/get-convex/convex-backend/main/Justfile ``` -------------------------------- ### Get User Identity in Convex Function (TypeScript) Source: https://stack.convex.dev/nextauth This TypeScript code snippet demonstrates how to retrieve the authenticated user's identity within a Convex query function. It assumes the query is called after authentication and uses `ctx.auth.getUserIdentity()` to get the user's subject (ID), which is then used to fetch the user document from the 'users' table in Convex. The function returns the user document. ```typescript import { query } from "./_generated/server"; import { Id } from "./_generated/dataModel"; export const viewerInfo = query({ args: {}, handler: async (ctx) => { // Assuming this query is only called after authentication const { subject: userId } = (await ctx.auth.getUserIdentity())!; return await ctx.db.get(userId as Id<"users">); }, }); ``` -------------------------------- ### Run Other Convex CLI Commands Locally Source: https://stack.convex.dev/building-the-oss-backend After setting up the local backend, you can use standard Convex CLI commands like `run` and `env` directly, just as you would with the cloud development flow. These commands will now target your local instance. ```bash # Example: Run a Convex function locally just convex run # Example: Manage Convex environment variables locally just convex env ``` -------------------------------- ### Start React Native Project Source: https://stack.convex.dev/user-authentication-with-clerk-and-convex This command starts the React Native application. Ensure the Convex development server is running before executing this command. ```bash bun start ``` -------------------------------- ### Safe Date Conversion (TypeScript) Source: https://stack.convex.dev/nextauth-adapter A utility function that converts a numerical timestamp (or undefined) into a Date object, returning null if the input is undefined. This is useful for handling optional date fields. ```typescript function maybeDate(value: number | undefined) { return value === undefined ? null : new Date(value); } ``` -------------------------------- ### Convex Environment Variable Check Source: https://stack.convex.dev/nextauth-adapter This TypeScript code checks for the presence of the CONVEX_AUTH_ADAPTER_SECRET environment variable and throws an error if it's missing. It's crucial for securing communication between Next.js and Convex. ```typescript if (process.env.CONVEX_AUTH_ADAPTER_SECRET === undefined) { throw new Error("Missing CONVEX_AUTH_ADAPTER_SECRET environment variable"); } ``` -------------------------------- ### Install OpenAI Node SDK (Beta) Source: https://stack.convex.dev/gpt-streaming-with-persistent-reactivity Installs the beta version of the OpenAI Node.js SDK, which is required for streaming capabilities. This is a prerequisite for using the streaming features. ```bash 1npm install openai 2 ``` -------------------------------- ### Convert Object to Database Format (TypeScript) Source: https://stack.convex.dev/nextauth-adapter This generic TypeScript function `toDB` converts an object into a format suitable for database storage. It transforms Date objects to timestamps and null values to undefined. ```typescript function toDB( obj: T, ): { [K in keyof T]: T[K] extends Date ? number : null extends T[K] ? undefined : T[K]; } { const result: any = {}; for (const key in obj) { const value = obj[key]; result[key] = value instanceof Date ? value.getTime() : value === null ? undefined : value; } return result; } ``` -------------------------------- ### Install Tiptap React and Starter Kit Source: https://stack.convex.dev/add-a-collaborative-document-editor-to-your-app Installs the Tiptap editor core library along with the starter kit for basic functionality. This is a prerequisite for using Tiptap with React. ```bash npm i @tiptap/react @tiptap/starter-kit ```