Composables
useConvexAction
Execute Convex actions for external API calls.
Call a Convex action for external API calls or long-running tasks.
Usage
app/components/Summarize.vue
<script setup lang="ts">
import { api } from '#convex/api'
const { execute: summarize, isLoading, error } = useConvexAction(api.ai.summarize)
const result = ref('')
async function handleSummarize(text: string) {
result.value = await summarize({ text })
}
</script>
<template>
<div>
<button :disabled="isLoading" @click="handleSummarize('Some text to summarize')">
{{ isLoading ? 'Processing...' : 'Summarize' }}
</button>
<p v-if="result">
{{ result }}
</p>
<p v-if="error">
{{ error.message }}
</p>
</div>
</template>
Parameters
| Parameter | Type | Description |
|---|---|---|
action | FunctionReference | The Convex action to call |
Return Values
| Property | Type | Description |
|---|---|---|
execute | (args) => Promise<T> | Call the action |
isLoading | Ref<boolean> | True while running |
error | Ref<Error | null> | Error if action failed |
Actions vs Mutations
Use mutations for database operations. Use actions when you need to:
- Call external APIs (payment providers, AI services)
- Perform operations that shouldn't be transactional
- Use Node.js APIs not available in mutations
| Feature | Mutation | Action |
|---|---|---|
| Database access | Direct | Via ctx.runMutation() |
| External APIs | No | Yes |
| Transactional | Yes | No |
| Retries | Automatic | Manual |
Example: Payment Processing
app/components/Checkout.vue
<script setup lang="ts">
import { api } from '#convex/api'
const { execute: processPayment, isLoading } = useConvexAction(api.payments.process)
async function handleCheckout(amount: number) {
const result = await processPayment({ amount, currency: 'usd' })
if (result.success) {
navigateTo('/order-confirmation')
}
}
</script>
The payment action calls an external payment provider, then saves the result using a mutation:
convex/payments.ts
import { v } from 'convex/values'
import { api } from './_generated/api'
import { action } from './_generated/server'
export const process = action({
args: { amount: v.number(), currency: v.string() },
handler: async (ctx, { amount, currency }) => {
// Call external payment API
const result = await stripe.charges.create({ amount, currency })
// Save result to database
await ctx.runMutation(api.orders.create, {
chargeId: result.id,
amount,
status: result.status,
})
return { success: result.status === 'succeeded' }
},
})