Router context
Learn how to use the router context in your app.
Built-in context#
The router context is a shared object that is available to all procedures.
It contains the following properties:
ctx.session
- The current session, if available.ctx.db
- The Drizzle database instance.ctx.adapters
- Adapters for interacting with external services.ctx.logger
- A logger instance.
Session#
The session object contains information about the current user. It's signature depends on the used authentication provider and extends this base interface.
export interface Session {user: {id: stringemail?: stringname?: string}}
Database#
The Drizzle instance is available on ctx.db
and can be used to interact with the database.
It's recommended to use services to interact with the database and keep the API layer thin.
Adapters#
Adapters are used to interact with external services in a standardized way.
ctx.adapters.billing
- The billing adapter, currently only Stripe
is supported.
Logger#
The logger instance is available on ctx.logger
and can be used to log messages.
This wraps console.log
by default, but you can drop in your own logger, like pino
.
// Log a messagectx.logger.info('Hello world')// Error, will be shown in the consolectx.logger.error('Something went wrong')// Debug, only shown when `debug` is enabledctx.logger.debug('Hello world')
Extending the context#
You can extend the context by adding your own properties in the createTRPCContext
helper function.
Edit packages/api/trpc/context.ts
and add your own properties:
//...export const createTRPCContext = async <TSession extends Session = Session,Adapters extends ApiAdapters = ApiAdapters,>(opts: {headers: Headerssession: TSession | nulladapters: Adaptersdebug?: boolean}) => {const { session, adapters, debug } = optsconst logger = {info: console.log,error: console.error,debug: (...args: any[]) => {if (debug) {console.log(...args)}},}if (debug) {const source = opts.headers.get('x-trpc-source') ?? 'unknown'console.log('>>> tRPC Request from', source, 'by', session?.user)}return {session,db,adapters,logger,// Add your own properties heremyCustomProperty: 'Hello world',}}
You can now access ctx.myCustomProperty
in your procedures. Types are automatically inferred.
//...publicProcedure.mutation(async ({ ctx, input }) => {console.log(ctx.myCustomProperty)}),
Was this helpful?