### Convex Project Setup: Installation and Development Server Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/QUICK_REFERENCE.md Install the Convex package using npm and start the local development server using the `npx convex dev` command. ```bash npm install convex npx convex dev ``` -------------------------------- ### Complete React Setup with ConvexProvider Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/ConvexProvider.md A full example of setting up ConvexProvider in a React application, including rendering the root component and strict mode. ```typescript import { ConvexReactClient, ConvexProvider } from "convex/react"; import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; import "./index.css"; // Create the Convex client const convex = new ConvexReactClient( process.env.REACT_APP_CONVEX_URL! ); // Render with provider ReactDOM.createRoot(document.getElementById("root")!).render( ); ``` -------------------------------- ### Install Convex.js Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/README.md Command to install the convex.js library using npm. ```bash npm install convex ``` -------------------------------- ### Install Convex AI Files Source: https://github.com/get-convex/convex-js/blob/main/src/cli/lib/aiFiles/MANUAL_TESTING.md Installs AI files for the project. Verify that skills are written to the correct agent-specific locations. ```bash npx convex ai-files install ``` -------------------------------- ### Complete Schema Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Schema.md A comprehensive example demonstrating the definition of multiple tables with various index types, including regular, search, and vector indexes. ```typescript import { defineTable, defineSchema } from "convex/server"; import { v } from "convex/values"; export default defineSchema({ users: defineTable({ email: v.string(), name: v.string(), avatar: v.optional(v.string()), role: v.union(v.literal("admin"), v.literal("user")), createdAt: v.number(), }) .index("by_email", ["email"]) .index("by_createdAt", ["createdAt"]), posts: defineTable({ authorId: v.id("users"), title: v.string(), content: v.string(), contentEmbedding: v.array(v.number()), published: v.boolean(), tags: v.array(v.string()), createdAt: v.number(), updatedAt: v.number(), }) .index("by_authorId", ["authorId"]) .index("by_published_createdAt", ["published", "createdAt"]) .searchIndex("search_content", { searchField: "content", filterFields: ["published", "tags"], }) .vectorIndex("vector_content", { vectorField: "contentEmbedding", filterFields: ["published"], }), comments: defineTable({ postId: v.id("posts"), authorId: v.id("users"), content: v.string(), createdAt: v.number(), }) .index("by_postId", ["postId"]) .index("by_authorId", ["authorId"]) .index("by_postId_createdAt", ["postId", "createdAt"]), likes: defineTable({ postId: v.id("posts"), userId: v.id("users"), createdAt: v.number(), }) .index("by_postId", ["postId"]) .index("by_userId", ["userId"]) .index("by_postId_userId", ["postId", "userId"]), }); ``` -------------------------------- ### Complete File Upload and Management Setup Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Storage.md Provides a comprehensive server-side setup for handling file uploads, storing references in the database, retrieving file URLs, and deleting files. ```typescript import { mutation, query } from "./_generated/server"; import { v } from "convex/values"; // Get an upload URL for the client export const generateUploadUrl = mutation({ handler: async (ctx) => { return await ctx.storage.generateUploadUrl(); }, }); // Store file reference in database export const saveFile = mutation({ args: { userId: v.id("users"), storageId: v.string(), fileName: v.string(), }, handler: async (ctx, args) => { await ctx.db.patch(args.userId, { fileId: args.storageId, fileName: args.fileName, }); }, }); // Get file URL export const getFileUrl = query({ args: { userId: v.id("users") }, handler: async (ctx, args) => { const user = await ctx.db.get(args.userId); if (!user?.fileId) return null; return await ctx.storage.getUrl(user.fileId); }, }); // Delete file export const deleteFile = mutation({ args: { userId: v.id("users") }, handler: async (ctx, args) => { const user = await ctx.db.get(args.userId); if (user?.fileId) { await ctx.storage.delete(user.fileId); await ctx.db.patch(args.userId, { fileId: undefined }); } }, }); ``` -------------------------------- ### Complete Query Example with Index, Order, and Take Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Query.md A comprehensive example demonstrating how to construct a query using `withIndex` for efficient filtering, `order` for sorting, and `take` for limiting results. This pattern is common for fetching recent or specific sets of data. ```typescript export const getRecentUserTasks = query({ args: { userId: v.id("users"), limit: v.optional(v.number()), }, handler: async (ctx, args) => { const tasks = await ctx.db .query("tasks") // Use index for efficient filtering .withIndex("by_userId_createdAt", (q) => q.eq("userId", args.userId) .gte("createdAt", Date.now() - 7 * 24 * 60 * 60 * 1000) ) // Sort newest first .order("desc") // Limit results .take(args.limit ?? 20); return tasks; }, }); ``` -------------------------------- ### Initialize Convex Development Environment Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/README.md Command to start the local development server for Convex. ```bash npx convex dev ``` -------------------------------- ### Document Example with Interface Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/types.md Provides an example of defining a specific document interface, extending the base Document type with custom fields like name and email for a User document. ```typescript interface User extends Document { _id: Id<"users">; _creationTime: number; name: string; email: string; } ``` -------------------------------- ### List Skills Source: https://github.com/get-convex/convex-js/blob/main/src/cli/lib/aiFiles/MANUAL_TESTING.md Lists all installed skills in JSON format. Used to verify the presence or absence of skills after performing install or remove operations. ```bash npx skills ls --json ``` -------------------------------- ### Query Context Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/FunctionContext.md Example of using QueryCtx to access database and authentication information within a query function. Imports 'query' from './_generated/server'. ```typescript import { query } from "./_generated/server"; export const getUser = query({ args: { userId: v.id("users") }, handler: async (ctx, args) => { // Access database const user = await ctx.db.get(args.userId); // Check authentication const identity = await ctx.auth.getUserIdentity(); return user; }, }); ``` -------------------------------- ### Complete Server-Side Pagination Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Pagination.md A comprehensive example of server-side pagination for tasks, including arguments for user ID, cursor, and limit. It returns items, a boolean indicating if more items are available, and the next cursor. ```typescript export const listTasks = query({ args: { userId: v.id("users"), cursor: v.optional(v.string()), limit: v.optional(v.number()), }, returns: v.object({ items: v.array(v.object({ _id: v.id("tasks"), title: v.string(), })), hasMore: v.boolean(), nextCursor: v.optional(v.string()), }), handler: async (ctx, args) => { const { page, isDone, continueCursor } = await ctx.db .query("tasks") .withIndex("by_userId_status", (q) => q.eq("userId", args.userId).eq("status", "active") ) .order("desc") .paginate({ cursor: args.cursor, numItems: args.limit ?? 10, }); return { items: page, hasMore: !isDone, nextCursor: isDone ? undefined : continueCursor, }; }, }); ``` -------------------------------- ### Typed Functions Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/ServerFunctions.md Demonstrates the usage of generated typed query, mutation, and action functions for type-safe backend operations. Includes examples for fetching tasks, creating tasks, and sending notifications. ```typescript import { query, mutation, action } from "./_generated/server"; import { v } from "convex/values"; export const getTasks = query({ args: { userId: v.id("users") }, handler: async (ctx, args) => { return await ctx.db .query("tasks") .withIndex("by_userId", (q) => q.eq("userId", args.userId)) .collect(); }, }); export const createTask = mutation({ args: { userId: v.id("users"), title: v.string() }, returns: v.id("tasks"), handler: async (ctx, args) => { return await ctx.db.insert("tasks", { userId: args.userId, title: args.title, completed: false, createdAt: Date.now() }); }, }); export const sendNotification = action({ args: { userId: v.id("users"), message: v.string() }, handler: async (ctx, args) => { // Can call queries, mutations, and external APIs const user = await ctx.runQuery(internal.users.get, { userId: args.userId }); await ctx.scheduler.runAfter(0, internal.notifications.deliver, { userId: args.userId, message: args.message }); }, }); ``` -------------------------------- ### Server-Side Pagination Query Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Pagination.md Example of using the `paginate` method on a Convex query to fetch a page of tasks for a specific user. It demonstrates how to handle cursor, number of items, and retrieve pagination status. ```typescript import { query } from "./_generated/server"; import { v } from "convex/values"; export const listTasks = query({ args: { userId: v.id("users"), cursor: v.optional(v.string()), }, handler: async (ctx, args) => { const { page, isDone, continueCursor } = await ctx.db .query("tasks") .withIndex("by_userId", (q) => q.eq("userId", args.userId)) .order("desc") .paginate({ cursor: args.cursor, numItems: 20, }); return { page, isDone, continueCursor }; }, }); ``` -------------------------------- ### Example: Get Function Metadata Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/FunctionContext.md Demonstrates how to access function metadata within a query handler. Note that the metadata object might be directly available in the context. ```typescript import { query } from "./_generated/server"; export const getMetadata = query({ handler: async (ctx) => { // Get metadata about function execution // (metadata object may be available in context) return { status: "executed", timestamp: Date.now(), }; }, }); ``` -------------------------------- ### ConvexProvider with Auth0 Authentication Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/ConvexProvider.md Integrate ConvexProvider with Auth0 authentication. This example shows how to get an access token and set it on the Convex client when the user is authenticated. ```typescript import { ConvexReactClient, ConvexProvider } from "convex/react"; import { useAuth } from "@auth0/auth0-react"; // or your auth provider import App from "./App"; const client = new ConvexReactClient( process.env.REACT_APP_CONVEX_URL ); function AppWithAuth() { const { isLoading, isAuthenticated, getAccessTokenSilently } = useAuth(); React.useEffect(() => { if (isAuthenticated) { // Get token and set on client getAccessTokenSilently().then((token) => { client.setAuth(token); }); } else { client.clearAuth(); } }, [isAuthenticated, getAccessTokenSilently]); if (isLoading) { return
Loading...
; } return ( ); } ``` -------------------------------- ### Client-Side Environment Variables Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/configuration.md Examples of environment variables for configuring Convex clients in different frontend frameworks. ```bash # React apps (create-react-app) REACT_APP_CONVEX_URL=https://your-project.convex.cloud # Next.js NEXT_PUBLIC_CONVEX_URL=https://your-project.convex.cloud # Vue, generic VITE_CONVEX_URL=https://your-project.convex.cloud ``` -------------------------------- ### Parallel Processing with splitCursor Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Pagination.md Demonstrates splitting a cursor for parallel processing of paginated data. This example shows how to get the first page, process it, and then schedule a subsequent batch using a split cursor. Requires `convex`. ```typescript export const batchProcessTasks = action({ args: { userId: v.id("users") }, handler: async (ctx, args) => { // Get first page to get cursor const { continueCursor, page } = await ctx.db .query("tasks") .withIndex("by_userId", (q) => q.eq("userId", args.userId)) .paginate({ numItems: 1000 }); // Process current page for (const task of page) { // Process task } if (!continueCursor) { console.log("Done!"); return; } // Split cursor for parallel processing const split1 = continueCursor; // Or use splitCursor(0.5) // Schedule another batch await ctx.scheduler.runAfter( 1000, internal.batch.processTasks, { userId: args.userId, cursor: split1 } ); }, }); ``` -------------------------------- ### Query documents with filters and ordering Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/DatabaseWriter.md Use `query` to start building a query on a specific table. Chain methods like `withIndex`, `order`, and `take` to filter, sort, and limit results. This example fetches the 10 most recent users created after a specific time. ```typescript const recentUsers = await ctx.db .query("users") .withIndex("by_creationTime", (q) => q.gte("_creationTime", cutoffTime)) .order("desc") .take(10); ``` -------------------------------- ### Basic ConvexProvider Setup Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/ConvexProvider.md Wrap your root component with ConvexProvider to make the Convex client available. Ensure the REACT_APP_CONVEX_URL environment variable is set. ```typescript import { ConvexReactClient, ConvexProvider } from "convex/react"; import App from "./App"; const client = new ConvexReactReactClient( process.env.REACT_APP_CONVEX_URL ); export function Root() { return ( ); } ``` -------------------------------- ### Server-Side Environment Variables Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/configuration.md Examples of environment variables for server-side Convex functions (Actions), such as API keys and database credentials. ```bash # Email service API key SENDGRID_API_KEY=sg_... # Database credentials DATABASE_URL=postgresql://... # Third-party API keys STRIPE_API_KEY=sk_... OPENAI_API_KEY=sk-... ``` -------------------------------- ### Action Context Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/FunctionContext.md Example of using ActionCtx to run queries, mutations, and external API calls within an action function. Imports 'action' from './_generated/server', 'internal' from './_generated/api', and 'v' from 'convex/values'. ```typescript import { action } from "./_generated/server"; import { internal } from "./_generated/api"; import { v } from "convex/values"; export const sendWelcomeEmail = action({ args: { userId: v.id("users") }, handler: async (ctx, args) => { // Call a query to get user data const user = await ctx.runQuery( internal.users.getUser, { userId: args.userId } ); // Call external API (HTTP request) const response = await fetch("https://api.sendgrid.com/v3/mail/send", { method: "POST", headers: { "Authorization": `Bearer ${process.env.SENDGRID_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ to: user.email, subject: "Welcome!", html: "

Welcome to our app

", }), }); if (!response.ok) { throw new Error("Failed to send email"); } // Call mutation to mark email as sent await ctx.runMutation( internal.users.markEmailSent, { userId: args.userId } ); }, }); ``` -------------------------------- ### Mutation Context Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/FunctionContext.md Example of using MutationCtx to interact with the database, authentication, and scheduler within a mutation function. Imports 'mutation' from './_generated/server', 'internal' from './_generated/api', and 'v' from 'convex/values'. ```typescript import { mutation } from "./_generated/server"; import { internal } from "./_generated/api"; import { v } from "convex/values"; export const createPost = mutation({ args: { title: v.string(), content: v.string(), }, handler: async (ctx, args) => { const identity = await ctx.auth.getUserIdentity(); if (!identity) { throw new ConvexError("Not authenticated"); } // Write to database const postId = await ctx.db.insert("posts", { title: args.title, content: args.content, authorId: identity.subject, createdAt: Date.now(), }); // Schedule email notification await ctx.scheduler.runAfter( 0, internal.email.notifyFollowers, { postId, authorId: identity.subject } ); return postId; }, }); ``` -------------------------------- ### Request Handling Examples Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Router.md Demonstrates how to parse query parameters, JSON bodies, form data, and raw request bodies within your HTTP route handlers. ```APIDOC ## Request Handling ### Parsing Query Parameters ```typescript const url = new URL(request.url); const searchParams = url.searchParams; const limit = searchParams.get("limit"); // string or null const offset = searchParams.get("offset"); ``` ### Parsing JSON Body ```typescript const body = await request.json(); const { name, email } = body; ``` ### Parsing Form Data ```typescript const formData = await request.formData(); const file = formData.get("file"); // File object const text = formData.get("text"); // string ``` ### Reading Raw Body ```typescript const text = await request.text(); const arrayBuffer = await request.arrayBuffer(); ``` ``` -------------------------------- ### Setup ConvexProvider in React Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/QUICK_REFERENCE.md Integrate Convex into your React application by setting up `ConvexReactClient` and `ConvexProvider`. Ensure your Convex URL is set in environment variables. ```typescript // src/main.tsx import { ConvexReactClient, ConvexProvider } from "convex/react"; const client = new ConvexReactClient(process.env.REACT_APP_CONVEX_URL); ReactDOM.createRoot(document.getElementById("root")!).render( ); ``` -------------------------------- ### WithoutSystemFields Usage Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/types.md Demonstrates the usage of WithoutSystemFields to create a new user object without system fields, ready for insertion into the database. ```typescript const newUser: WithoutSystemFields = { name: "Alice", email: "alice@example.com" }; await ctx.db.insert("users", newUser); ``` -------------------------------- ### Install a Convex Skill Manually Source: https://github.com/get-convex/convex-js/blob/main/src/cli/lib/aiFiles/MANUAL_TESTING.md Installs a specific Convex skill manually using the 'skills add' command. This is part of the test flow to verify that the CLI no longer relies on local tracked skill names for removal. ```bash npx skills add get-convex/agent-skills --skill convex-quickstart --agent codex --yes ``` -------------------------------- ### Calling Queries from Actions Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/FunctionContext.md Example of how to invoke a query function from within an action context using `ctx.runQuery`. ```typescript const items = await ctx.runQuery( api.items.list, { limit: 10 } ); ``` -------------------------------- ### Clerk Authentication Setup Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/configuration.md Integrate Clerk for authentication by wrapping your app with ClerkProvider and ClerkConvexProvider. Ensure your publishable key is set in environment variables. ```typescript import { ClerkConvexProvider } from "convex/react-clerk"; import { ClerkProvider } from "@clerk/clerk-react"; {/* Your app */} ``` -------------------------------- ### Query User Profile with Auth Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/FunctionContext.md Example of how to query user data using authentication context. Ensure to handle the case where the user is not authenticated. ```typescript export const getMyProfile = query({ handler: async (ctx) => { const identity = await ctx.auth.getUserIdentity(); if (!identity) { return null; // No auth } const user = await ctx.db .query("users") .withIndex("by_subject", (q) => q.eq("subject", identity.subject)) .first(); return user; }, }); ``` -------------------------------- ### Configure Authentication Providers in Convex Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Authentication.md Sets up authentication providers for your Convex project using `defineAuth`. This example configures GitHub as a provider. Requires importing 'defineAuth' from '@convex-dev/auth/server' and the specific provider (e.g., GitHub) from '@auth.js/core/providers/github'. ```typescript import { defineAuth } from "@convex-dev/auth/server"; import GitHub from "@auth.js/core/providers/github"; export const { auth, signIn, signOut, store } = defineAuth({ providers: [GitHub], }); ``` -------------------------------- ### Calling Queries from Mutations Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/FunctionContext.md Example of how to invoke a query function from within a mutation context using `ctx.runQuery`. ```typescript const userData = await ctx.runQuery( internal.users.getUser, { userId } ); ``` -------------------------------- ### Convex Client Setup Options Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/QUICK_REFERENCE.md Configure the Convex client with various options like authentication, logging, and timeouts. Supports React, HTTP, and a base client for advanced use cases. ```typescript // React const client = new ConvexReactClient(url, { auth: token, logger: false, timeoutMs: 30000, }); // HTTP const client = new ConvexHttpClient(url); // Base client (advanced) const client = new BaseConvexClient(url); ``` -------------------------------- ### Create an HTTP Router Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Router.md Use httpRouter to create a new instance for defining HTTP routes. This is the starting point for setting up your HTTP API. ```typescript import { httpRouter } from "convex/server"; export const http = httpRouter(); // Define routes http.route({ method: "GET", path: "/api/hello", handler: async (request) => { return new Response("Hello, World!"); }, }); // Define POST route http.route({ method: "POST", path: "/api/data", handler: async (request) => { const body = await request.json(); return new Response(JSON.stringify({ received: body }), { status: 200, headers: { "Content-Type": "application/json" }, }); }, }); ``` -------------------------------- ### Applying Transaction Limits Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/FunctionContext.md Example of how to pass transaction limits when calling `runQuery`. These limits help control resource consumption per statement. ```typescript const result = await ctx.runQuery( myQuery, { arg: "value" }, { transactionLimits: { maxReadsPerSingleStatement: 100 } } ); ``` -------------------------------- ### Calling Mutations from Actions Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/FunctionContext.md Example of how to invoke a mutation function from within an action context using `ctx.runMutation`. ```typescript await ctx.runMutation( internal.tasks.markComplete, { taskId } ); ``` -------------------------------- ### Schedule Batch Job Processing Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Scheduler.md This example shows how to schedule a batch job for processing after a delay and how to continue processing in batches. It saves the job to the database and then schedules the initial processing action. ```typescript import { mutation, action } from "./_generated/server"; import { internal } from "./_generated/api"; import { v } from "convex/values"; export const queueBatchJob = mutation({ args: { data: v.array(v.string()) }, handler: async (ctx, args) => { // Save job to database const jobId = await ctx.db.insert("jobs", { data: args.data, status: "queued", createdAt: Date.now(), }); // Schedule processing to happen after a delay await ctx.scheduler.runAfter(5000, internal.jobs.processBatch, { jobId, }); return jobId; }, }); export const processBatch = action({ args: { jobId: v.id("jobs") }, handler: async (ctx, args) => { const job = await ctx.runQuery(internal.jobs.getJob, { jobId: args.jobId }); // Process items in batches const batchSize = 10; for (let i = 0; i < job.data.length; i += batchSize) { const batch = job.data.slice(i, i + batchSize); // Process batch for (const item of batch) { // Do work... } // Schedule next batch if needed if (i + batchSize < job.data.length) { await ctx.scheduler.runAfter(1000, internal.jobs.continueBatch, { jobId: args.jobId, offset: i + batchSize, }); break; // Current action exits, next one continues } } // Mark job complete await ctx.runMutation(internal.jobs.updateJobStatus, { jobId: args.jobId, status: "complete", }); }, }); ``` -------------------------------- ### first Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Query.md Get the first result from the query, or null if no matches are found. This is a convenient method for retrieving a single expected document. ```APIDOC ## first ### Description Get the first result from the query, or null if no matches. ### Method ```typescript first(): Promise ``` ### Parameters None ### Returns Promise - Promise resolving to the first document or null ### Example ```typescript const firstTask = await ctx.db .query("tasks") .first(); ``` ``` -------------------------------- ### Defining a Record with Specific Value Type Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/types.md Examples of creating key-value maps using `v.record()`, specifying key and value types. ```typescript // Map of user IDs to scores const scoresByUser = v.record(v.string(), v.number()); // Map of strings to arrays of strings const tagsByCategory = v.record(v.string(), v.array(v.string())); ``` -------------------------------- ### Next.js App Router Setup with ConvexProvider Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/ConvexProvider.md Configure ConvexProvider in the root layout for Next.js applications using the App Router. Ensure NEXT_PUBLIC_CONVEX_URL is set. ```typescript import { ConvexReactClient, ConvexProvider } from "convex/react"; import "./globals.css"; const convex = new ConvexReactClient( process.env.NEXT_PUBLIC_CONVEX_URL! ); export const metadata = { title: "My App", }; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` -------------------------------- ### Complete Semantic Search Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/SearchAndVector.md This snippet demonstrates a full semantic search implementation in Convex, including generating embeddings, storing articles with their embeddings, and performing semantic searches. ```typescript import { action } from "./_generated/server"; import { v } from "convex/values"; import { internal } from "./_generated/api"; // Generate embedding for a query export const generateEmbedding = action({ args: { text: v.string() }, returns: v.array(v.number()), handler: async (ctx, args) => { const response = await fetch("https://api.openai.com/v1/embeddings", { method: "POST", headers: { "Authorization": `Bearer ${process.env.OPENAI_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ input: args.text, model: "text-embedding-3-small", }), }); const data = await response.json(); return data.data[0].embedding; }, }); // Store article with embedding export const storeArticle = mutation({ args: { title: v.string(), content: v.string(), }, handler: async (ctx, args) => { // Generate embedding for the content const embedding = await ctx.runAction( internal.search.generateEmbedding, { text: args.content } ); // Store with embedding return await ctx.db.insert("articles", { title: args.title, content: args.content, contentEmbedding: embedding, createdAt: Date.now(), }); }, }); // Search semantically export const searchArticles = query({ args: { query: v.string() }, handler: async (ctx, args) => { // Get embedding for the search query const embedding = await ctx.runAction( internal.search.generateEmbedding, { text: args.query } ); // Search for similar articles return await ctx.db .query("articles") .vectorSearch("vector_content", embedding) .limit(10) .collect(); }, }); ``` -------------------------------- ### Authentication Check in a Query Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/errors.md An example of a query that first checks for user authentication using `ctx.auth.getUserIdentity()` and throws a `ConvexError` if the user is not authenticated. ```typescript export const getProfile = query({ handler: async (ctx) => { const identity = await ctx.auth.getUserIdentity(); if (!identity) { throw new ConvexError("Must be authenticated"); } // Continue with authenticated user... }, }); ``` -------------------------------- ### Basic Convex Authentication Setup in React Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Authentication.md Integrates Convex authentication into a React application using `ConvexProvider` and `ConvexAuthState`. Handles loading states and redirects unauthenticated users to a login page. Requires importing `ConvexProvider`, `ConvexReactClient`, `useAuth` from 'convex/react' and `ConvexAuthState` from '@convex-dev/auth/react'. ```typescript import { ConvexProvider, ConvexReactClient, useAuth } from "convex/react"; import { ConvexAuthState } from "@convex-dev/auth/react"; const client = new ConvexReactClient(process.env.REACT_APP_CONVEX_URL); export function App() { return ( ); } function YourApp() { const { user, isLoading } = useAuth(); if (isLoading) return
Loading...
; if (!user) { return ; } return ; } ``` -------------------------------- ### useAction Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Hooks.md Get a function to execute an action on the server. The returned function takes arguments and returns a Promise that resolves with the action's return value. ```APIDOC ## useAction ### Description Get a function to execute an action on the server. ### Parameters #### Path Parameters - **action** (FunctionReference<"action">) - Required - Reference to the action function ### Returns A function that executes the action and returns a Promise. ### Example ```typescript import { useAction } from "convex/react"; import { api } from "../convex/_generated/api"; function SendEmail() { const sendEmail = useAction(api.email.send); const handleSend = async () => { const result = await sendEmail({ to: "user@example.com", subject: "Hello" }); console.log("Email sent:", result); }; return ; } ``` ``` -------------------------------- ### Next.js Pages Router Setup with ConvexProvider Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/ConvexProvider.md Set up ConvexProvider in the _app.tsx file for Next.js applications using the Pages Router. This makes the Convex client available to all pages. ```typescript import type { AppProps } from "next/app"; import { ConvexReactClient, ConvexProvider } from "convex/react"; const convex = new ConvexReactClient( process.env.NEXT_PUBLIC_CONVEX_URL! ); export default function App({ Component, pageProps }: AppProps) { return ( ); } ``` -------------------------------- ### take Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Query.md Get up to N results from the query. This method is useful for retrieving a limited number of documents, often used in conjunction with other filters or ordering. ```APIDOC ## take ### Description Get up to N results from the query. ### Method ```typescript take(numItems: number): Promise ``` ### Parameters - **numItems** (number) - Required - Maximum number of documents to return ### Returns Promise - Promise resolving to an array of documents (may have fewer items) ### Example ```typescript const first10Tasks = await ctx.db .query("tasks") .take(10); const limitedResults = await ctx.db .query("tasks") .withIndex("by_status", (q) => q.eq("status", "active")) .take(5); ``` ``` -------------------------------- ### Example: Deleting a Post with Authorization Checks Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/errors.md Illustrates a mutation that checks for authentication, post existence, and author ownership before deleting a post, throwing `ConvexError` for each condition. ```typescript export const deletePost = mutation({ args: { postId: v.id("posts") }, handler: async (ctx, args) => { const identity = await ctx.auth.getUserIdentity(); if (!identity) { throw new ConvexError("Must be authenticated to delete posts"); } const post = await ctx.db.get(args.postId); if (!post) { throw new ConvexError("Post not found"); } if (post.authorId !== identity.subject) { throw new ConvexError("Only the author can delete this post"); } await ctx.db.delete(args.postId); }, }); ``` -------------------------------- ### Define Basic HTTP Endpoints with httpRouter Methods Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Router.md Utilize shortcut methods like .get(), .post(), .delete() on the httpRouter instance to define specific HTTP routes. Handles GET, POST, and DELETE requests with path parameters. ```typescript import { httpRouter } from "convex/server"; export const http = httpRouter(); // GET endpoint http.get("/api/greeting", async (request) => { const name = new URL(request.url).searchParams.get("name") ?? "World"; return new Response(`Hello, ${name} દૂર!`); }); // POST endpoint with JSON body http.post("/api/create", async (request) => { const body = await request.json(); return new Response( JSON.stringify({ success: true, data: body }), { status: 201, headers: { "Content-Type": "application/json" }, } ); }); // GET with path parameters http.get("/api/users/:id", async (request) => { const url = new URL(request.url); const id = url.pathname.split("/")[3]; // Extract from path return new Response(JSON.stringify({ userId: id }), { headers: { "Content-Type": "application/json" }, }); }); // DELETE endpoint http.delete("/api/items/:id", async (request) => { return new Response(null, { status: 204 }); }); ``` -------------------------------- ### HTTP Action Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/ServerFunctions.md Defines an HTTP action that can handle incoming webhooks. It processes JSON payloads for POST requests to the /webhook endpoint and returns a JSON response or a 404 for other requests. ```typescript import { httpActionGeneric } from "convex/server"; import { httpRouter } from "convex/server"; export const api = httpActionGeneric({ handler: async (ctx, request) => { const path = new URL(request.url).pathname; if (path === "/webhook" && request.method === "POST") { const payload = await request.json(); // Process webhook return new Response(JSON.stringify({ success: true }), { status: 200, headers: { "Content-Type": "application/json" } }); } return new Response("Not found", { status: 404 }); }, }); ``` -------------------------------- ### Query using Search Index with Filters Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Schema.md Combine full-text search with field filtering using `.search()` and `.eq()` methods. This example searches for a term and filters by `userId`. ```typescript // With filters const filtered = await ctx.db .query("documents") .search("search_content", (q) => q.term("convex").eq("userId", myId) ) .collect(); ``` -------------------------------- ### React usePaginatedQuery Hook Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Pagination.md Example of using the `usePaginatedQuery` hook in a React component to display a list of tasks. It shows how to handle loading states and load more results. ```typescript import { usePaginatedQuery } from "convex/react"; import { api } from "../convex/_generated/api"; function TaskList({ userId }) { const { results, status, loadMore, } = usePaginatedQuery( api.tasks.list, { userId }, { initialNumItems: 10 } ); if (results === undefined) { return
Loading initial results...
; } return (
{results.map(task => (
{task.title}
))} {status === "CanLoadMore" && ( )} {status === "LoadingMore" && (
Loading more...
)} {status === "Exhausted" && (
No more results
)}
); } ``` -------------------------------- ### Vector Search Query Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/SearchAndVector.md Example of a Convex query function for semantic search. It first generates an embedding for the query string and then uses it to find documents with similar embeddings in the 'articles' table. ```typescript export const semanticSearch = query({ args: { query: v.string(), limit: v.optional(v.number()), }, handler: async (ctx, args) => { // 1. Generate embedding for query (using OpenAI or similar) const embedding = await generateEmbedding(args.query); // 2. Search for similar documents const results = await ctx.db .query("articles") .vectorSearch("vector_content", embedding) .limit(args.limit ?? 10) .collect(); return results; }, }); ``` -------------------------------- ### Instantiate ConvexHttpClient Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/ConvexHttpClient.md Create a new instance of ConvexHttpClient. Provide the URL of your Convex deployment. Authentication tokens can be set initially via options. ```typescript import { ConvexHttpClient } from "convex/browser"; const client = new ConvexHttpClient( process.env.CONVEX_URL ); // Execute a query const tasks = await client.query(api.tasks.list); // Execute a mutation const newId = await client.mutation(api.tasks.create, { text: "Buy milk" }); ``` -------------------------------- ### Full-Text Search Query Example Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/SearchAndVector.md Example of a Convex query function that performs a full-text search on the 'documents' table using a defined search index. It searches for a specific term and limits the results. ```typescript export const searchDocuments = query({ args: { query: v.string(), limit: v.optional(v.number()), }, handler: async (ctx, args) => { const results = await ctx.db .query("documents") .search("search_content", (q) => q.term(args.query) ) .take(args.limit ?? 10); return results; }, }); ``` -------------------------------- ### Initialize ConvexReactClient Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/ConvexReactClient.md Instantiate ConvexReactClient with your Convex deployment URL. Optionally, provide an authentication token fetcher. ```typescript import { ConvexReactClient } from "convex/react"; // Basic initialization const convex = new ConvexReactClient( process.env.REACT_APP_CONVEX_URL ); // With authentication const convex = new ConvexReactClient( process.env.REACT_APP_CONVEX_URL, { auth: async () => { const response = await fetch("/api/auth/token"); return response.json(); } } ); ``` -------------------------------- ### Scope operations to a table Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/DatabaseWriter.md Use `table` to get a fluent API for database operations scoped to a specific table. This allows chaining methods like `get`, `query`, `insert`, `patch`, `replace`, and `delete` directly on the table object. ```typescript const user = await ctx.db.table("users").get(userId); await ctx.db.table("users").patch(userId, { name: "Updated" }); ``` -------------------------------- ### Initialize ConvexReactClient and ConvexProvider Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/ConvexProvider.md Set up the ConvexReactClient with your Convex URL from an environment variable and wrap your entire React application with ConvexProvider. This ensures that Convex hooks are available throughout your app and handles auto-reconnection. ```typescript import React from "react"; import ReactDOM from "react-dom/client"; import { ConvexReactClient, ConvexProvider } from "convex/react"; import App from "./App"; import "./index.css"; const convex = new ConvexReactClient( process.env.REACT_APP_CONVEX_URL! ); ReactDOM.createRoot(document.getElementById("root")!).render( ); ``` -------------------------------- ### Get Convex Connection State with useConvexConnectionState Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Hooks.md Use `useConvexConnectionState` to get the current WebSocket connection state. It returns one of the following states: "connecting", "connected", "authExpired", or "closed". ```typescript import { useConvexConnectionState } from "convex/react"; function ConnectionStatus() { const state = useConvexConnectionState(); return
Connection: {state}
; } ``` -------------------------------- ### useQuery Usage Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/configuration.md Illustrates the basic usage of the useQuery hook. Currently, no additional options are supported beyond the query reference and arguments. ```typescript const result = useQuery(queryRef, ...args, options); ``` -------------------------------- ### Get Function Name Utility Source: https://github.com/get-convex/convex-js/blob/main/api-extractor-configs/reports/server.api.md Retrieves the name of a given function reference. ```typescript export function getFunctionName(functionReference: AnyFunctionReference): string; ``` -------------------------------- ### get Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/DatabaseWriter.md Fetches a single document by its ID. Returns the document object or null if not found. ```APIDOC ## get ### Description Fetch a single document by its ID. ### Method get ### Parameters #### Path Parameters - `table` (string) - Required - Name of the table - `id` (string) - Required - The ID of the document to fetch ### Returns Promise - The document object or `null` if not found ### Example ```typescript const user = await ctx.db.get("users", userId); if (user) { console.log(user.name); } ``` ``` -------------------------------- ### client.action Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/ConvexHttpClient.md Executes an action against the Convex deployment and returns the result. Actions can perform side effects and are executed asynchronously. ```APIDOC ## Method action ### Description Executes an action against the Convex deployment and returns the result. Actions can perform side effects and are executed asynchronously. ### Method `action` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **action** (FunctionReference<"action">) - Required - Reference to the action function. - **args** (Record) - Optional - Arguments to pass to the action. ### Request Example None provided ### Response #### Success Response - **Promise** - Resolves to the action result. #### Response Example None provided ``` -------------------------------- ### Defining an Array of Objects Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/types.md Example of creating a schema for an array where each element is an object with specific fields. ```typescript const tasks = v.array( v.object({ id: v.id("tasks"), title: v.string(), completed: v.boolean(), }) ); ``` -------------------------------- ### Convex.js Project File Structure Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/README.md Illustrates the directory layout for the convex.js project, including source code organization, configuration files, and compiled output. ```bash convex-js/ ├── src/ │ ├── server/ # Server-side code │ ├── react/ # React hooks and client │ ├── browser/ # Browser clients │ ├── values/ # Value types and validation │ ├── nextjs/ # Next.js helpers │ ├── react-auth0/ # Auth0 integration │ ├── react-clerk/ # Clerk integration │ └── cli/ # CLI implementation ├── package.json ├── tsconfig.json └── dist/ # Compiled output ``` -------------------------------- ### Defining a Required Object Field Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/types.md Example of creating a Convex object schema where all fields are required. ```typescript // Without optional const user = v.object({ name: v.string(), // required email: v.string(), // required }); ``` -------------------------------- ### Calling Queries from Actions Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/FunctionContext.md Shows how to execute a query function from an action function using `ctx.runQuery`. ```APIDOC ### Calling Queries from Actions ```typescript const items = await ctx.runQuery( api.items.list, { limit: 10 } ); ``` ``` -------------------------------- ### collect Source: https://github.com/get-convex/convex-js/blob/main/_autodocs/api-reference/Query.md Execute the query and get all results. This method retrieves all documents that match the query criteria. ```APIDOC ## collect ### Description Execute the query and get all results. ### Method ```typescript collect(): Promise ``` ### Parameters None ### Returns Promise - Promise resolving to an array of all matching documents ### Example ```typescript const allTasks = await ctx.db .query("tasks") .collect(); ``` ```