Metadata
On this page
Procedure metadata allows you to add an optional procedure specific meta property which will be available in all middleware function parameters.
Create router with typed metadata
import { initTRPC } from '@trpc/server';
type Context = { user: { name: string } | null };
interface Meta {
authRequired: boolean;
}
export const t = initTRPC.context<Context>().meta<Meta>().create();
export const appRouter = t.router({
// [...]
});Example with per route authentication settings
server.ts
import { initTRPC, TRPCError } from '@trpc/server';
type Context = { user: { name: string } | null };
interface Meta {
authRequired: boolean;
}
export const t = initTRPC.context<Context>().meta<Meta>().create();
export const authedProcedure = t.procedure.use(async (opts) => {
const { meta, next, ctx } = opts;
// only check authorization if enabled
if (meta?.authRequired && !ctx.user) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return next();
});
export const appRouter = t.router({
hello: authedProcedure.meta({ authRequired: false }).query(() => {
return {
greeting: 'hello world',
};
}),
protectedHello: authedProcedure.meta({ authRequired: true }).query(() => {
return {
greeting: 'hello-world',
};
}),
});Default meta, chaining, and shallow merging
You can set default values for your meta type, and if you chain meta on top of a base procedure it will be shallow merged.
import { initTRPC } from '@trpc/server';
type Context = { user: { name: string } | null };
interface Meta {
authRequired?: boolean;
role?: 'user' | 'admin'
}
export const t = initTRPC
.context<Context>()
.meta<Meta>()
.create({
// Set a default value
defaultMeta: { authRequired: false }
});
const authMiddleware = t.middleware((opts) => opts.next());
const publicProcedure = t.procedure
// ^ Default Meta: { authRequired: false }
const authProcedure = publicProcedure
.use(authMiddleware)
.meta({
authRequired: true,
role: 'user'
});
// ^ Meta: { authRequired: true, role: 'user' }
const adminProcedure = authProcedure
.meta({
role: 'admin'
});
// ^ Meta: { authRequired: true, role: 'admin' }