### 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
);
}
```
--------------------------------
### 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