Mocha
Mocha
TTCTheo's Typesafe Cult
Created by Mocha on 4/11/2025 in #questions
App Router & tRPC Server Cache
How do you handle caching server queries with tRPC? I refuse to believe there's no good & easy way to do that. What am I missing? Client Components feel faster as it's easy to cache the response on client. Server Components feel fast on first load but trigger queries on every render, making it feel slower. Currently using: * tRPC v11 * Next.js v15.3.0 * TanStack React Query v5.72 The last question about this that I could find was somehow from exactly 1 year ago and still hasn't been resolved.
2 replies
TTCTheo's Typesafe Cult
Created by Mocha on 8/26/2024 in #questions
Migrating from T3 to T3 Turborepo
I have an existing T3 web app (Next, Clerk, tRPC) and I'm developing a mobile version. How can I utilize the existing tRPC endpoints and Clerk auth? I know there's a monorepo sample that Theo went over in some videos, but I'm not starting from scratch.
13 replies
TTCTheo's Typesafe Cult
Created by Mocha on 7/19/2024 in #questions
Creating video from images
I have a lot of images in a page, and I want to allow my users to download the images as a video. It'd be great if that can be done on the client side so I don't have to think about or pay for servers. I tried @ffmpeg/ffmpeg but it gives the following error message, even when exactly following the example provided
ModuleBuildError: ./node_modules/@ffmpeg/ffmpeg/dist/esm/classes.js:104:28
Module not found
102 | if (!this.#worker) {
103 | this.#worker = classWorkerURL ?
> 104 | new Worker(new URL(classWorkerURL, import.meta.url), {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
105 | type: "module",
106 | }) :
107 | // We need to duplicated the code here to enable webpack
ModuleBuildError: ./node_modules/@ffmpeg/ffmpeg/dist/esm/classes.js:104:28
Module not found
102 | if (!this.#worker) {
103 | this.#worker = classWorkerURL ?
> 104 | new Worker(new URL(classWorkerURL, import.meta.url), {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
105 | type: "module",
106 | }) :
107 | // We need to duplicated the code here to enable webpack
My goal is to basically implement this function:
async function downloadVideo(images: string[]) {
const downloadUrl = 'TODO'
const a = document.createElement('a')
a.href = videoUrl
a.download = 'output.mp4'
a.click()
a.remove()
}
async function downloadVideo(images: string[]) {
const downloadUrl = 'TODO'
const a = document.createElement('a')
a.href = videoUrl
a.download = 'output.mp4'
a.click()
a.remove()
}
2 replies
TTCTheo's Typesafe Cult
Created by Mocha on 5/13/2024 in #questions
Next.js API Type Safety without tRPC?
I'm having issues with tRPC and am thinking of removing it from my project. Since I'm using App Router, it's less of a problem when calls are made on the server. However, I still need to make calls from client side. What are some good solutions for that?
10 replies
TTCTheo's Typesafe Cult
Created by Mocha on 5/12/2024 in #questions
[TRPCClientError]: Converting circular structure to JSON
I'm getting this error only in production (Vercel). I'm using tRPC, Supabase, Clerk. The website crashes right after login. Browser error:
Application error: a server-side exception has occurred (see the server logs for more information).
Vercel logs:
l [TRPCClientError]: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at l.from (/var/task/.next/server/chunks/696.js:7:53047)
at /var/task/.next/server/app/activity/page.js:1:48095
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
meta: undefined,
shape: undefined,
data: undefined,
digest: '2788403914',
[cause]: TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at JSON.stringify (<anonymous>)
... 5 lines matching cause stack trace ...
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
code: 'INTERNAL_SERVER_ERROR',
name: 'TRPCError',
[cause]: TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at JSON.stringify (<anonymous>)
at /var/task/.next/server/chunks/101.js:1:12977
at t (/var/task/.next/server/chunks/338.js:13:359299)
at a (/var/task/.next/server/chunks/338.js:13:359613)
at c (/var/task/.next/server/chunks/338.js:13:353322)
at /var/task/.next/server/app/activity/page.js:1:47939
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
}
}
l [TRPCClientError]: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at l.from (/var/task/.next/server/chunks/696.js:7:53047)
at /var/task/.next/server/app/activity/page.js:1:48095
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
meta: undefined,
shape: undefined,
data: undefined,
digest: '2788403914',
[cause]: TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at JSON.stringify (<anonymous>)
... 5 lines matching cause stack trace ...
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
code: 'INTERNAL_SERVER_ERROR',
name: 'TRPCError',
[cause]: TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Timeout'
| property '_idlePrev' -> object with constructor 'TimersList'
--- property '_idleNext' closes the circle
at JSON.stringify (<anonymous>)
at /var/task/.next/server/chunks/101.js:1:12977
at t (/var/task/.next/server/chunks/338.js:13:359299)
at a (/var/task/.next/server/chunks/338.js:13:359613)
at c (/var/task/.next/server/chunks/338.js:13:353322)
at /var/task/.next/server/app/activity/page.js:1:47939
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
}
}
9 replies
TTCTheo's Typesafe Cult
Created by Mocha on 4/3/2024 in #questions
Failed to compile. Entry point for implicit type library 'mime'
I suddenly started getting this error message when trying to compile. The dev server works fine. I tried installing @types/mime and including "types": ["node"] in my tsconfig.json/compileOptions. The same error message appears on Vercel as well, so it's nothing about my setup. I suspected it could be caused by some JSON imports, so I appended with { type: 'json' } to my imports.
$ next build
▲ Next.js 14.1.4
- Environments: .env

Linting and checking validity of types .Failed to compile.

Type error: Cannot find type definition file for 'mime'.
The file is in the program because:
Entry point for implicit type library 'mime'

error: script "build" exited with code 1
$ next build
▲ Next.js 14.1.4
- Environments: .env

Linting and checking validity of types .Failed to compile.

Type error: Cannot find type definition file for 'mime'.
The file is in the program because:
Entry point for implicit type library 'mime'

error: script "build" exited with code 1
2 replies
TTCTheo's Typesafe Cult
Created by Mocha on 3/30/2024 in #questions
TRPCClientError: Unable to transform response from server
I just migrated from Next Auth to Clerk. Clerk is working fine. tRPC works fine too, but I keep getting this error message from all requests. src/pages/_app.tsx
// ...
return
<ClerkProvider {...pageProps}>
{/* Everything else goes in here */}
</ClerkProvider>
// ...
export default api.withTRPC(MyApp)
// ...
return
<ClerkProvider {...pageProps}>
{/* Everything else goes in here */}
</ClerkProvider>
// ...
export default api.withTRPC(MyApp)
src/api/trpc.ts
import { clerkClient, getAuth } from '@clerk/nextjs/server'

export const createTRPCContext = async ({ req }: CreateNextContextOptions) => {
const session = getAuth(req)
const user = session.userId
? await clerkClient.users.getUser(session.userId)
: null

return {
userId: session?.userId ?? undefined,
orgId: session.orgId ?? undefined,
firstName: user?.firstName,
prisma,
}
}

const t = initTRPC.context<typeof createTRPCContext>().create({
transformer: superjson,
errorFormatter({ shape, error }) {
return {
...shape,
data: {
...shape.data,
zodError:
error.cause instanceof ZodError ? error.cause.flatten() : null,
},
}
},
})
import { clerkClient, getAuth } from '@clerk/nextjs/server'

export const createTRPCContext = async ({ req }: CreateNextContextOptions) => {
const session = getAuth(req)
const user = session.userId
? await clerkClient.users.getUser(session.userId)
: null

return {
userId: session?.userId ?? undefined,
orgId: session.orgId ?? undefined,
firstName: user?.firstName,
prisma,
}
}

const t = initTRPC.context<typeof createTRPCContext>().create({
transformer: superjson,
errorFormatter({ shape, error }) {
return {
...shape,
data: {
...shape.data,
zodError:
error.cause instanceof ZodError ? error.cause.flatten() : null,
},
}
},
})
3 replies
TTCTheo's Typesafe Cult
Created by Mocha on 3/5/2024 in #questions
TRPCClientError: Unexpected token 'A', "An error o"... is not valid JSON
I'm making a fetch API call to an external server inside a tRPC route. It works perfectly on localhost, but never works when deployed on Vercel. The request normally takes ~30s, and it has a large body (~12KB).
10 replies
TTCTheo's Typesafe Cult
Created by Mocha on 2/7/2024 in #questions
How to Refetch in App Router?
How do I refetch/revalidate data loaded from Server Components? I have a Server Component page with a Client Component inside it
export default async function Parent() {
return <Child data={await api.route.data.query()} />
}
export default async function Parent() {
return <Child data={await api.route.data.query()} />
}
Normally, when I useMutation I call query.refetch(). How do I do that here without causing a full page refresh?
5 replies
TTCTheo's Typesafe Cult
Created by Mocha on 8/23/2023 in #questions
~/components vs ~/components/Button
Any opinions on this? Does A affect performance? (importing from a file that exports many other components) A
// ~/components/index.ts
export { default as Button } from './Button'
export { default as Label } from './Label'
export { default as Toggle } from './Toggle'

// ~/components/Button/Button.tsx
export default function Button() { return <button /> }

// ~/components/Button/index.ts
export { default } from './Button'

// ~/pages/index.tsx
import { Button, Label } from '~/components'
// ~/components/index.ts
export { default as Button } from './Button'
export { default as Label } from './Label'
export { default as Toggle } from './Toggle'

// ~/components/Button/Button.tsx
export default function Button() { return <button /> }

// ~/components/Button/index.ts
export { default } from './Button'

// ~/pages/index.tsx
import { Button, Label } from '~/components'
B
// ~/components/Button/Button.tsx
export default function Button() { return <button /> }

// ~/components/Button/index.ts
export { default } from './Button'

// ~/pages/index.tsx
import Button from '~/components/Button'
import Label from '~/components/Label'
// ~/components/Button/Button.tsx
export default function Button() { return <button /> }

// ~/components/Button/index.ts
export { default } from './Button'

// ~/pages/index.tsx
import Button from '~/components/Button'
import Label from '~/components/Label'
18 replies
TTCTheo's Typesafe Cult
Created by Mocha on 8/7/2023 in #questions
How to deploy API to Vercel
What's the easiest way to deploy a basic API endpoint to Vercel? I made an Express app structured like:
api
|--- index.js
package.json
pnpm-lock.yaml
vercel.json
api
|--- index.js
package.json
pnpm-lock.yaml
vercel.json
api/index.js:
import express from 'express'
import cors from 'cors'

const app = express()

// Disable CORS rules
app.use(cors())

app.get('/', (req, res) => {
res.send('It works!')
})

const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
console.log(`API listening on PORT ${PORT} `)
})

export default app
import express from 'express'
import cors from 'cors'

const app = express()

// Disable CORS rules
app.use(cors())

app.get('/', (req, res) => {
res.send('It works!')
})

const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
console.log(`API listening on PORT ${PORT} `)
})

export default app
vercel.json:
{
"version": 2,
"builds": [
{
"src": "index.js",
"use": "@now/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "index.js"
}
]
}
{
"version": 2,
"builds": [
{
"src": "index.js",
"use": "@now/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "index.js"
}
]
}
The API just uploads files to S3 or GCS, so I'm open to using any other language or framework. It will mainly be used in my T3 app, but I found Next.js really confusing with handling files (tried to use HTML form, formidable, multer, ...) Docs I followed: * https://vercel.com/docs/concepts/functions/serverless-functions/runtimes/node-js * https://vercel.com/guides/using-express-with-vercel#standalone-express
6 replies
TTCTheo's Typesafe Cult
Created by Mocha on 6/24/2023 in #questions
Simplest useInfiniteQuery implementation?
I'm trying to enable useInfiniteQuery on a tRPC query. I saw several tutorials, but it looked very different every time. My current setup looks something like:
vendors: protectedProcedure
.input(z.object({
take: z.number().default(10),
cursor: z.number().nullish(),
}))
.query(async ({ ctx: { prisma }, input: { take, cursor } }) => {
type Vendor = { vendor_id: string }

return prisma.$queryRaw<Vendor[]>`
select vendor_id
from vendor
limit ${take}
offset 0`
// how to use cursor here? ^
// not using .findMany()
}),
vendors: protectedProcedure
.input(z.object({
take: z.number().default(10),
cursor: z.number().nullish(),
}))
.query(async ({ ctx: { prisma }, input: { take, cursor } }) => {
type Vendor = { vendor_id: string }

return prisma.$queryRaw<Vendor[]>`
select vendor_id
from vendor
limit ${take}
offset 0`
// how to use cursor here? ^
// not using .findMany()
}),
Then:
const { data: vendors = [] } = api.accounts.vendors.useQuery({})
const { data: vendors = [] } = api.accounts.vendors.useQuery({})
4 replies
TTCTheo's Typesafe Cult
Created by Mocha on 6/15/2023 in #questions
tRPC + Clerk: user & org info
I'm switching from NextAuth to Clerk. With NextAuth, I got the user info like:
import type { Session } from 'next-auth'

type CreateContextOptions = {
session: Session | null
}
import type { Session } from 'next-auth'

type CreateContextOptions = {
session: Session | null
}
With Clerk's getAuth, I only get userId and nothing else about the user. It exists in the SignedInAuthObject type but it's always undefined, so I can't read the user's email or orgSlug in my tRPC context. I can retrieve it like this, but it'd be called too many times and retrieve too much data
export const createTRPCContext = async (opts: CreateNextContextOptions) => {
// Get the session from the server using the getServerSession wrapper function
const session = getAuth(opts.req)
const { userId } = session
if (!userId) return createInnerTRPCContext({ session })

const user = await clerkClient.users.getUser(userId)
const orgs = await clerkClient.users.getOrganizationMembershipList({ userId })

return createInnerTRPCContext({
session,
user,
orgSlug: orgs[0]?.organization?.slug,
})
}
export const createTRPCContext = async (opts: CreateNextContextOptions) => {
// Get the session from the server using the getServerSession wrapper function
const session = getAuth(opts.req)
const { userId } = session
if (!userId) return createInnerTRPCContext({ session })

const user = await clerkClient.users.getUser(userId)
const orgs = await clerkClient.users.getOrganizationMembershipList({ userId })

return createInnerTRPCContext({
session,
user,
orgSlug: orgs[0]?.organization?.slug,
})
}
tRPC setup: t3 then https://clerk.com/docs/nextjs/trpc
43 replies
TTCTheo's Typesafe Cult
Created by Mocha on 12/29/2022 in #questions
tRPC + WebSocket Client
14 replies
TTCTheo's Typesafe Cult
Created by Mocha on 12/13/2022 in #questions
Read input from many child components
I have a page with hundreds of text fields. From the page, I'm trying to read the user's input from each field when they click on a button. useState can work but would be too slow What would be a better solution? Should/how do I use useRef in this case?
20 replies
TTCTheo's Typesafe Cult
Created by Mocha on 12/9/2022 in #questions
Netlify – tRPC crashes after every deployment
8 replies