oRPC
background

Server Actions

Leverage oRPC for type-safe and powerful server actions

Introduction

oRPC makes it simple to implement server actions, offering a robust and type-safe way to manage server-side logic. Server actions are supported out of the box and are powered by several key features:

Requirements

To use a procedure as a server action, the procedure must either:

  1. Be directly callable, or
  2. Use Calling Procedures with Context to create a callable procedure with context.

Usage

"use server"
 
import { ,  } from '@orpc/server'
import {  } from 'zod'
import {  } from 'next/headers'
import {  } from "next/navigation"
import {  } from '@orpc/zod'
 
const  = .(async (, , ) => {
      const  = await ()
      const  = .('Authorization') ? { : 'example' } : 
 
      if(!) {
          throw new ({ : 'UNAUTHORIZED' })
      }
 
      return .({
          : {
              ,
          }
      })
})
 
export const  = 
  .()
  .(
    .({
      : .(),
      : .({
        : .(),
        : .().('image/*').(),
      }),
    }),
  )
  .((, , ) => {
    // ^ context.user is automatically injected
     ('/some-where') // or return some thing
  })

Form Integration

Integrate server actions seamlessly with React forms for automatic type coercion:

import {  } from 'examples/server-action'
import * as React from 'react'
 
export default function () {
  return (
    < ={}>
      {/* Auto convert 1992 to bigint */}
      < ="number" ="id" ="1992" />
      {/* Auto parse user object */}
      < ="text" ="user[name]" ="Unnoq" />
      <
        ="avatar"
        ="file"
        ="user[avatar]"
        ="image/*"
      />
    </>
  )
}

Thanks to Smart Conversion, and Bracket Notation, automatically convert 1992 into a bigint and seamlessly parse objects like user.

Direct Client Calls

Call server actions directly from client components for greater flexibility:

"use client"
 
import {  } from 'examples/server-action'
import * as React from 'react'
 
export default function () {
  async function () {
    const  = (.('avatar') as HTMLInputElement).
 
    // Call with plain object - types are preserved
    await ({
      : 1992n,
      : {
        : 'Unnoq',
        : ?.[0],
      },
    })
  }
 
  return < ={}>Update User</>
}

Server Actions with Context

Some procedures cannot be used as server actions directly. This is typically because they require additional context, such as user information or other runtime data. In such cases, you can use createProcedureCaller to provide the required context dynamically, making the procedure callable and usable as a server action.

import { ,  } from '@orpc/server'
import {  } from 'zod'
 
type  = { ?: { : string } }
 
const  = 
.<>()
.(.({ : .() }))
.(({  }) => `Hello, ${}!`)
 
getting({ : 'Unnoq' }) // ❌ cannot call this procedure directly, and cannot be used as a server action
This expression is not callable. Type 'Procedure<Context, undefined, ZodObject<{ name: ZodString; }, "strip", ZodTypeAny, { name: string; }, { name: string; }>, undefined, string> & { ...; }' has no call signatures.
export const = ({ : , : async () => { // you can access headers, cookies, etc. here to create context return { : { : 'example' } } }, }) ({ : 'Unnoq' }) // ✅ can call this procedure directly, and can be used as a server action

On this page