Skip to Content
API ReferenceHooksuseNexusMutation

useNexusMutation

useNexusMutation is a client-side hook for performing “write” operations (e.g., POST, PUT, DELETE). It manages the pending state, result, and provides lifecycle callbacks for side effects like revalidation or showing notifications.

Import

import { useNexusMutation } from "next-nexus/client";

Core Concepts

How It Works

You provide a factory function that takes variables and returns a definition for a POST, PUT, PATCH, or DELETE request. The hook returns a mutate function that you can call to trigger the request.

Concurrency Guard

The hook prevents concurrent mutations. If mutate or mutateAsync is called while a request is already in-flight, it will throw an error. You should always check the isPending state to disable UI elements and prevent this.

Lifecycle Callbacks

The options object accepts several callback functions (onStart, onSuccess, onError, onSettled) that allow you to run side effects at different stages of the mutation lifecycle. This is the ideal place to perform actions like client-side cache revalidation or optimistic updates.

Signature

Parameters

  • factory: (variables: TVariables) => NexusDefinition<TData> — A function that accepts mutation variables and returns a definition.
  • options?: An optional object to configure the hook. See Options below.

Return Value

An object containing:

  • data: TData | undefined (the data from the last successful mutation)
  • headers: Headers | undefined
  • error: TError | null
  • isPending, isSuccess, isError: boolean
  • mutate: (variables: TVariables) => void (fire-and-forget)
  • mutateAsync: (variables: TVariables) => Promise<TData>
  • reset: () => void (resets the hook’s state)

Options

  • route?: string - Proxies the request through a Next.js Route Handler.
  • onStart?: (variables: TVariables) => TContext | Promise<TContext> - Fires before the mutation. Can return a context value that is passed to other callbacks.
  • onSuccess?: (data: TData, variables: TVariables, context?: TContext) => void | Promise<void> - Fires on success.
  • onError?: (error: TError, variables: TVariables, context?: TContext) => void | Promise<void> - Fires on error.
  • onSettled?: (data?: TData, error?: TError, variables: TVariables, context?: TContext) => void | Promise<void> - Fires after the mutation succeeds or fails.

Examples

Basic Mutation

Call mutate with variables to trigger the mutation. Use onSuccess to revalidate client-side caches.

"use client"; import { useNexusMutation, revalidateClientTags } from "next-nexus/client"; import { productDefinition } from "@/api/productDefinition"; export function LikeButton({ id }: { id: string }) { const { mutate, isPending } = useNexusMutation(productDefinition.like, { onSuccess: () => { // Invalidate and refetch any queries using this tag revalidateClientTags(["products"]); }, }); return ( <button onClick={() => mutate(id)} disabled={isPending}> {isPending ? "Liking…" : "Like"} </button> ); }

Using a route Proxy

Proxy the request through an internal API route instead of calling the external API directly from the client.

"use client"; import { useNexusMutation } from "next-nexus/client"; import { productDefinition } from "@/api/productDefinition"; export function SaveButton({ id, name }: { id: string; name: string }) { const { mutate, isPending } = useNexusMutation(productDefinition.update, { route: "/api/internal/save", }); return ( <button onClick={() => mutate({ id, name })} disabled={isPending}> Save </button> ); }

See also

Last updated on