#Schema Enums
1 messages · Page 1 of 1 (latest)
Convex schemas do not use TypeScript enums directly, even when using a Postgres database as the backend. Instead, Convex recommends modeling enum-like fields using unions of string literals with the validator system. For example:
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
myTable: defineTable({
status: v.union(
v.literal("pending"),
v.literal("approved"),
v.literal("rejected")
),
}),
});
This approach works regardless of whether Convex is running on its default backend or using Postgres/MySQL in a self-hosted setup. Convex abstracts away the underlying database, so you do not interact with Postgres enums directly. Instead, you define your allowed values at the application layer using Convex's validators, and Convex enforces these constraints for you.
If you need to extract TypeScript types from these validators, you can use the Infer helper:
import { v, Infer } from "convex/values";
export const statusValidator = v.union(
v.literal("pending"),
v.literal("approved"),
v.literal("rejected")
);
export type Status = Infer<typeof statusValidator>;
This gives you type safety throughout your app, matching the allowed values in your schema Types and Validators in TypeScript: A Convex Cookbook.
Note: When using static code generation (for large codebases), TypeScript enums are not supported in Convex schemas or API definitions; you should always use unions of string literal types instead Project Configuration.
In summary:
- Use
v.union(v.literal(...), ...)for enum-like fields in Convex schemas. - This is the recommended and supported approach, even with a Postgres backend.
- Do not use TypeScript enums in Convex schemas.
If you need to interact with native Postgres enums or extensions, Convex does not expose a direct mapping to those types, as Convex tables do not map directly to Postgres tables or types Discord: Postgres Extensions.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@onyx vigil Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
I'm sorry, but the knowledge sources provided do not contain specific, ready-to-use code examples for login.ts and signup.ts files tailored for a Next.js 15 app. The documentation covers authentication flows and integration patterns for Convex with various providers (such as Clerk, Auth0, Auth.js/NextAuth, and Convex Auth), but does not include standalone login.ts and signup.ts files for Next.js 15.
If you are using a specific authentication provider (e.g., Clerk, Auth0, Convex Auth, or NextAuth), you should follow the respective integration guides. For example:
- For Clerk: See the Convex & Clerk Next.js guide for how to set up authentication and wrap your app with the necessary providers.
- For Auth0: See the Convex & Auth0 guide for integration steps.
- For Convex Auth: See the Convex Auth setup guide for configuring authentication methods and building your UI.
If you clarify which authentication provider you are using, I can help you extract the relevant code snippets from the documentation. Otherwise, I'm unable to provide the exact login.ts and signup.ts files based on the current knowledge sources.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@onyx vigil Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
No, there is currently no way to define a timeout beyond the default 2 minutes for uploading files in Convex. The knowledge sources explicitly state that while there is no limit on the file size, the upload POST request has a 2 minute timeout. If the upload process takes longer than 2 minutes, the request will fail, and you will need to handle this scenario in your application, possibly by retrying the upload or notifying the user Convex File Upload Uploading files via upload URLs.
There is no mention in the documentation of a way to configure or extend this timeout.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@onyx vigil Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
The best way to use Zod with Convex is to leverage the community-supported helpers that allow you to validate function arguments and schemas using Zod, while still benefiting from Convex’s type safety and runtime validation.
For Function Argument Validation
You can use the withZod wrapper or the helpers from convex-helpers to validate arguments in your Convex functions. Here’s a typical pattern:
import { z } from "zod";
import { mutation } from "./_generated/server";
import { withZod } from "convex-helpers/server/zod";
export default mutation(
withZod({
args: {
body: z.string(),
author: z.string(),
},
handler: async ({ db }, { body, author }) => {
const message = { body, author };
return await db.insert("messages", message);
}
})
);
This ensures that your function arguments are validated at runtime using Zod, and you get end-to-end type safety in your TypeScript code Using withZod for input validation.
For Schema/Table Validation
If you want to define your database schema using Zod and convert it to a Convex validator, you can use zodToConvex or zodOutputToConvex:
import { z } from "zod";
import { defineTable } from "convex/server";
import { zodToConvex } from "convex-helpers/server/zod";
const userSchema = z.object({
name: z.string(),
email: z.string().email(),
});
export default defineTable(zodToConvex(userSchema));
Note: Zod can express more refined types than Convex’s validators (e.g., `.email()`), but Convex will only enforce what its own validator supports at the database level. For stricter validation, run Zod validation before writing to the database [Can I use Zod to define my database types too?](<https://stack.convex.dev/typescript-zod-function-validation#can-i-use-zod-to-define-my-database-types-too>).
### Summary
- Use `withZod` or `zCustomQuery`/`zCustomMutation` for function argument validation.
- Use `zodToConvex` or `zodOutputToConvex` to convert Zod schemas to Convex validators for table definitions.
- Remember: Convex enforces only what its validators support at the database level; use Zod for more refined validation in your application logic.
For more details and code samples, see the [Zod with TypeScript for Server-side Validation and End-to-End Types](<https://stack.convex.dev/typescript-zod-function-validation>) and [Wrappers as “Middleware” – Zod Validation](<https://stack.convex.dev/wrappers-as-middleware-zod-validation>) guides.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
@onyx vigil Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
Yes, you can create a Zod schema from a Convex schema using helper functions like convexToZod or convexToZodFields. These helpers convert Convex validators into Zod schemas or fields, allowing you to extend or reuse your Convex schema definitions in Zod.
For example, if you have a Convex validator:
export const userValidator = v.object({
name: v.string(),
age: v.number(),
});
You can convert it to a Zod schema like this:
import { convexToZod } from "convex-helpers/server/zod";
const zUser = convexToZod(userValidator);
If you want to extend the fields, you can use convexToZodFields:
import { convexToZodFields } from "convex-helpers/server/zod";
import { z } from "zod";
export const zUser = z.object({
...convexToZodFields(userValidator.fields),
email: z.string(),
});
This approach is confirmed in community discussions and is the recommended way to generate Zod schemas from Convex validators Help with convexToZod and spreading fields.
Note: Some advanced Zod features (like .extend() on the result of convexToZod) may require you to use the fields approach as shown above, since the direct result of convexToZod may not always be a Zod object schema.
In summary:
- Use
convexToZodorconvexToZodFieldsto generate Zod schemas from Convex validators. - This enables you to reuse and extend your Convex schema in Zod for further validation or type inference.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@onyx vigil Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
To emulate the backup and export functions available on Convex Cloud in your self-hosted Convex deployment, the recommended approach is to use the Convex CLI commands:
-
Export your data:
Use the following command to export your database state to a file:npx convex export --path <path-to-export-file>This will create a snapshot of your data, similar to the backup feature in the cloud product. The export is a ZIP file containing all documents in all tables, as well as file storage data if present Data Export Self-hosted README.
-
Import your data (for restore or migration):
To restore or migrate your data, use:npx convex import --replace-all <path-to-export-file>This will replace all existing data with the contents of your export file, emulating a restore operation Self-hosted README.
Notes:
- This process is the recommended and easiest way to handle backups and restores in self-hosted Convex, as described in the official self-hosted documentation.
- For production, ensure you stop external traffic before exporting to avoid data inconsistency, and consider automating regular exports for backup purposes Software upgrades.
- There is no built-in dashboard UI for backups in self-hosted Convex; all operations are performed via the CLI.
This approach closely matches the backup/export functionality provided in Convex Cloud, but is managed manually in self-hosted environments.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@onyx vigil Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
If you are using Postgres as your backing database and/or MinIO as your S3-compatible storage in a self-hosted Convex deployment, the recommended way to emulate backup/export functions is still to use the Convex CLI commands:
- Export:
npx convex export --path <path-to-export-file> - Import/Restore:
npx convex import --replace-all <path-to-export-file>
This process works regardless of whether you are using SQLite, Postgres, or MySQL as your database backend, and regardless of whether you are using local storage or S3-compatible storage (such as MinIO) for files. The export will include all table data and file storage, and the import will restore it into your deployment Self-hosted README: Migrating storage providers Self-hosted README: Running the database on Postgres or MySQL.
For S3-compatible storage (like MinIO):
- You need to set the appropriate environment variables, including
S3_ENDPOINT_URLfor MinIO or other S3-compatible services, as described in the self-hosted README. This ensures Convex stores and retrieves files from your MinIO bucket Self-hosted README: Using S3 Storage.
Summary:
- The backup/export and restore/import process is the same, regardless of your underlying database or storage provider.
- Just ensure your environment variables are set correctly for Postgres and MinIO.
- There is no mention in the knowledge sources of any additional steps or limitations specific to Postgres or MinIO for this process.
If you need to migrate between storage providers (e.g., from local to S3/MinIO), the process is to export from the old setup, configure the new storage, and import into the new setup Self-hosted README: Migrating storage providers.
If you encounter any issues specific to your storage or database provider, the documentation recommends reaching out to the Convex team for support.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@onyx vigil Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
Certainly! Here’s a focused overview of best practices and patterns for using Convex with a Next.js 15 app, especially in the context of Next.js Server Actions and the significance of Convex functions, with notes on the better-auth component.
1. Best Patterns for Next.js 15 + Convex
-
Provider Setup:
Wrap your app with the appropriate Convex provider (e.g.,ConvexProviderWithAuthorConvexProviderWithClerk) in a client component, and then include that provider in yourapp/layout.tsxor a similar root layout. This ensures authentication and Convex context are available throughout your app (Convex & Clerk Next.js, Convex Adapter for Auth.js). -
Authentication State:
Use Convex’suseConvexAuth()hook in client components to check authentication state before running queries or rendering protected content. This prevents unauthorized access and unnecessary backend calls (Authentication Best Practices). -
Custom Hooks:
Create custom hooks (e.g.,useAuthenticatedQueryWithStatus) to automatically skip queries when the user is not authenticated, reducing boilerplate and improving security (Authenticated Query Hooks).
2. Using Next.js Server Actions Properly
-
Calling Convex from Server Actions:
In Next.js 15, you can call Convex queries, mutations, and actions directly from Server Actions and Route Handlers usingfetchQuery,fetchMutation, andfetchActionfromconvex/nextjs. This is ideal for server-side data loading, mutations, and workflows that require secure, authenticated access (Server Actions and Route Handlers, Server-side authentication).import { api } from "@/convex/_generated/api"; import { fetchMutation, fetchQuery } from "convex/nextjs"; import { revalidatePath } from "next/cache"; export default async function PureServerPage() { const tasks = await fetchQuery(api.tasks.list, { list: "default" }); async function createTask(formData: FormData) { "use server"; await fetchMutation(api.tasks.create, { text: formData.get("text") as string }); revalidatePath("/example"); } // render tasks and task creation form return <form action={createTask}>...</form>; } -
Security Note:
Only call queries from GET requests; mutations and actions should be called from POST/PUT to avoid CSRF risks (Server-side authentication).
3. Significance of Convex Functions
- What Are Convex Functions?
Convex functions are your backend logic: queries (read), mutations (write), and actions (long-running/background tasks). They run in Convex’s backend and are invoked from your Next.js app, either client-side (via hooks) or server-side (via fetch functions) (Zen of Convex).
-
Why Use Them?
- Security: You can enforce authentication and authorization at the function level.
- Reactivity: Convex queries are live and reactive when used with client hooks.
- Separation of Concerns: Business logic lives in Convex, not in your frontend.
-
How to Call Them:
- Client Components: Use
useQuery,useMutation, anduseActionhooks. - Server Components/Actions: Use
fetchQuery,fetchMutation, andfetchAction(Next.js Server Rendering).
- Client Components: Use
-
Best Suited For:
- Real-time data (live queries)
- Secure, centralized business logic
- Collaborative and interactive applications
4. Using Convex Better-Auth
While the knowledge sources do not provide detailed documentation on the "better-auth" component, the general pattern is to ensure your Convex provider is set up to use the authentication context from your auth solution, and to use Convex’s authentication hooks and helpers to check and enforce authentication in both client and server code.
Summary:
- Use Convex providers and hooks for authentication and data access.
- Use Next.js Server Actions and Route Handlers to securely call Convex functions server-side.
- Write your business logic as Convex functions for security, reactivity, and maintainability.
- Always check authentication state before running queries or mutations, especially in client components.
If you need more specific guidance on "better-auth," please provide more details or refer to its documentation, as it is not covered in the current knowledge sources.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@onyx vigil Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
Certainly! Here’s what the knowledge sources say about using Convex functions with Next.js, and considerations for building a data access layer that could allow swapping out Convex for another backend.
Convex Functions vs. Next.js Actions
- Convex Functions (queries, mutations, actions) are the primary way to interact with your Convex backend. They encapsulate your business logic and database access, and are called from your Next.js app using either client-side hooks (
useQuery,useMutation) or server-side helpers (fetchQuery,fetchMutation,fetchAction) (Convex Functions Overview, Next.js Server Rendering). - Next.js Actions (Server Actions and Route Handlers) are a Next.js feature for handling HTTP requests and server-side logic. You can call Convex functions from within these actions using the fetch helpers, which is the recommended pattern for server-side data loading or mutations (Server Actions and Route Handlers).
When to use which:
- Use Convex functions for all business logic and data access that you want to keep backend-agnostic and reactive. This keeps your logic centralized and secure.
- Use Next.js Actions for orchestrating server-side workflows, integrating with other Next.js features (like revalidating paths), or when you need to combine Convex with other backend services in a single endpoint.
Creating a Data Access Layer
The knowledge sources do not provide a detailed pattern for abstracting Convex behind a data access layer, but you can infer a recommended approach:
-
Encapsulate Convex Calls:
Create a set of functions or classes in your Next.js app that wrap all calls to Convex (usingfetchQuery,fetchMutation, etc.). This way, your UI and business logic depend on your own interface, not directly on Convex. If you need to swap out Convex, you only need to reimplement this layer.// dataAccess.ts export async function getTasks() { return await fetchQuery(api.tasks.list, { list: "default" }); } -
Swap Backends:
If you later want to use a different backend, you can replace the implementation in your data access layer without changing your UI code.
Swapping Convex for Another Backend
- Convex functions are tightly integrated with Convex’s reactivity, security, and transactional guarantees. If you swap to another backend, you may lose these features unless you reimplement them.
- By using a data access layer, you can minimize the impact of such a swap, but you should be aware that features like real-time updates and transactional mutations are specific to Convex (Reactivity).
Summary Table
| Use Case | Use Convex Function | Use Next.js Action |
|---|---|---|
| Business logic & data access | ✅ | |
| Real-time/reactive data | ✅ | |
| Orchestrate workflows | ✅ | |
| Integrate with other APIs | ✅ | |
| Abstract backend for flexibility | ✅ (via wrapper) |
In summary:
- Use Convex functions for business logic, data access, and reactivity.
- Use Next.js Actions for server-side orchestration and integration.
- To enable backend swapping, wrap Convex calls in your own data access layer.
- Be aware that some Convex features (like reactivity) are not easily portable to other backends.
If you need more detailed patterns or code, the knowledge sources do not provide further specifics, but this approach aligns with the documented best practices (Next.js Server Rendering, Convex Functions).
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@onyx vigil Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
The main difference between the built-in S3 storage and the R2 component in Convex is how they are integrated and used within your Convex app:
Built-in S3 Storage:
- This is a storage backend option for self-hosted Convex deployments.
- You configure it by setting environment variables (e.g.,
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,S3_STORAGE_FILES_BUCKET, etc.) in your backend. Optionally, you can setS3_ENDPOINT_URLto use S3-compatible services like MinIO or Cloudflare R2. - It is used for storing Convex’s internal data, exports, snapshots, modules, files, and search indexes. The storage is managed at the infrastructure level and is not directly exposed as a programmable API for your app logic (Self-hosted README: Using S3 Storage).
R2 Component:
- This is a Convex Component that provides a programmable API for storing and serving files with Cloudflare R2 (or compatible S3 APIs).
- You install it as an npm package (
@convex-dev/r2) and configure it in your Convex app. It exposes methods and React hooks for uploading, storing, and retrieving files directly from your application code. - The R2 component is designed for app-level file storage (e.g., user uploads, media files) and integrates with your Convex database for metadata management. It provides a higher-level, developer-friendly API for file operations (Cloudflare R2 Component).
Summary Table:
| Feature | Built-in S3 Storage | R2 Component |
|---|---|---|
| Purpose | Backend infrastructure storage | App-level file storage API |
| Configuration | Environment variables | NPM package + Convex config |
| Usage | Internal Convex data, files, etc. | File uploads/downloads in app code |
| API for app developers | No | Yes (methods, hooks, metadata sync) |
| Supports S3-compatible | Yes (with endpoint override) | Yes (Cloudflare R2, S3 API) |
In short:
- Use built-in S3 storage for Convex’s infrastructure needs in self-hosted setups.
- Use the R2 component when you want to programmatically manage user files and integrate file storage into your app logic (Cloudflare R2 Component).
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@onyx vigil Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
No, the built-in S3 storage in Convex self-hosted is not intended to be used in the same way as the R2 component. The built-in S3 storage is designed for Convex’s internal infrastructure needs—such as storing exports, snapshots, modules, files, and search indexes—by configuring environment variables in your backend. It is not exposed as a programmable API for your application logic or for direct file management by your app users Using S3 Storage.
In contrast, the R2 component is specifically built to provide a developer-friendly, programmable API for storing and serving files from your application code. It offers methods and React hooks for uploading, storing, and retrieving files, and integrates with your Convex database for metadata management. This makes it suitable for user uploads, media files, and other app-level file storage needs Cloudflare R2 Component.
Why choose the R2 component over built-in S3 storage?
- The R2 component gives you a high-level API for file operations in your app, while built-in S3 storage is only for backend infrastructure.
- The R2 component is designed for app-level use cases, such as user uploads and serving files to users, which the built-in S3 storage does not support directly.
In summary:
If you need to manage files from your application logic (e.g., user uploads, media), use the R2 component. The built-in S3 storage is only for Convex’s internal backend needs and is not intended for direct use in your app code Cloudflare R2 Component Using S3 Storage.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@onyx vigil Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Let me check the knowledge base for you again. One moment! :books:
No, you cannot increase the Node.js or Convex runtime memory limits in your self-hosted environment. The memory limits are set as follows:
- Convex runtime: 64MB RAM
- Node.js runtime: 512MB RAM
These limits are the same for both the free and pro cloud plans, as well as for self-hosted deployments. The documentation and support threads confirm that these are hard limits, and there is no configuration option to increase them in self-hosted Convex. If you have a use case that requires higher limits, the official guidance is to contact the Convex team, but this is only mentioned for the cloud product and not for self-hosted environments (Function and action limits, State limits, Discord support thread).
“Actions time out after 10 minutes. Node.js and Convex runtime have 512MB and 64MB memory limit respectively. Please contact us if you have a use case that requires configuring higher limits.”
— Functions > Actions > Limits