Alex
Alexโ€ข13mo ago

Running TRPC on Vercel with custom serialization fails

Hi all, I'm having some difficulties with the serialization of my objects when I run on vercel. I'm running nextjs 13.4.4 with trpc/server,client,next 10.28.1 and the next page routing. I'm using a custom type "ts-money" which is returned in a trpc response like:
getSalaryEnvironment: protectedProcedure
.input(
z.object({
administratorId: z.string(),
salaryDate: salaryDateSchema,
}),
)
.query(async ({ input }) => {
return {
date: new Date(2023, 5, 31),
nbrOfDaysWorked: 20,
salaryDate: input.salaryDate,
totalGrossIncomeFromPreviousSalaryInYear: new Money(6000000,Currencies.EUR),
}
}),
getSalaryEnvironment: protectedProcedure
.input(
z.object({
administratorId: z.string(),
salaryDate: salaryDateSchema,
}),
)
.query(async ({ input }) => {
return {
date: new Date(2023, 5, 31),
nbrOfDaysWorked: 20,
salaryDate: input.salaryDate,
totalGrossIncomeFromPreviousSalaryInYear: new Money(6000000,Currencies.EUR),
}
}),
3 Replies
Alex
Alexโ€ข13mo ago
I have implemented a custom serialization for it like so:
import { Money } from 'ts-money'
import { z } from 'zod'

const moneySchema = z.object({
amount: z.number(),
currency: z.union([z.literal('EUR'), z.literal('USD'), z.literal('GBP')]),
})
export const initializeSuperJson = () => {
superjson.registerCustom(
{
isApplicable: (m): m is Money => {
return moneySchema.safeParse(m).success
},
serialize: (m: Money) => {
return { amount: m.amount, currency: m.currency }
},
deserialize: (json: { amount: number; currency: string }) => {
return new Money(json.amount, json.currency)
},
},
'Money',
)
}
import { Money } from 'ts-money'
import { z } from 'zod'

const moneySchema = z.object({
amount: z.number(),
currency: z.union([z.literal('EUR'), z.literal('USD'), z.literal('GBP')]),
})
export const initializeSuperJson = () => {
superjson.registerCustom(
{
isApplicable: (m): m is Money => {
return moneySchema.safeParse(m).success
},
serialize: (m: Money) => {
return { amount: m.amount, currency: m.currency }
},
deserialize: (json: { amount: number; currency: string }) => {
return new Money(json.amount, json.currency)
},
},
'Money',
)
}
It is injected in my singleton client (Using T3 approach) like so:
/**
* A set of typesafe react-query hooks for your tRPC API
*/
export const api = createTRPCNext<AppRouter>({
config() {
initializeSuperJson()
return {
/**
* Transformer used for data de-serialization from the server
* @see https://trpc.io/docs/data-transformers
**/
transformer: superjson,

/**
* Links used to determine request flow from client to server
* @see https://trpc.io/docs/links
* */
links: [
loggerLink({
enabled: (opts) =>
process.env.NODE_ENV === 'development' ||
(opts.direction === 'down' && opts.result instanceof Error),
}),
httpBatchLink({
url: `${getBaseUrl()}/api/trpc`,
}),
],
}
},
/**
* A set of typesafe react-query hooks for your tRPC API
*/
export const api = createTRPCNext<AppRouter>({
config() {
initializeSuperJson()
return {
/**
* Transformer used for data de-serialization from the server
* @see https://trpc.io/docs/data-transformers
**/
transformer: superjson,

/**
* Links used to determine request flow from client to server
* @see https://trpc.io/docs/links
* */
links: [
loggerLink({
enabled: (opts) =>
process.env.NODE_ENV === 'development' ||
(opts.direction === 'down' && opts.result instanceof Error),
}),
httpBatchLink({
url: `${getBaseUrl()}/api/trpc`,
}),
],
}
},
When I run it locally everything works as expected... But when deployed on vercel the custome serialization is not executed. I have added some logging and I can see the injection of custom serialization happening the first time I use a trpc route api.xxxx But the custom serilization does not take place. Any idea where I could start digging?
julius
juliusโ€ข13mo ago
GitHub
trpc/examples/next-13-starter/src/trpc/shared.ts at next13-auth ยท t...
๐Ÿง™โ€โ™€๏ธ Move Fast and Break Nothing. End-to-end typesafe APIs made easy. - trpc/examples/next-13-starter/src/trpc/shared.ts at next13-auth ยท trpc/trpc
Alex
Alexโ€ข13mo ago
Hi Julius, I will try this. Thanks for sharing.๐Ÿ‘ This did resolve my issue. thanks for sharring this example.