FluX
FluX
Explore posts from servers
TtRPC
Created by FluX on 3/23/2025 in #❓-help
v11 types ProcedureBuilder & MiddlewareBuilder
I would do this, but I'm not sure if this might break in the future
type Middleware = MiddlewareBuilder<object, object, object, unknown>
type Procedure = ProcedureBuilder<
object,
object,
object,
typeof unsetMarker,
typeof unsetMarker,
typeof unsetMarker,
typeof unsetMarker,
false
>
type Middleware = MiddlewareBuilder<object, object, object, unknown>
type Procedure = ProcedureBuilder<
object,
object,
object,
typeof unsetMarker,
typeof unsetMarker,
typeof unsetMarker,
typeof unsetMarker,
false
>
3 replies
TTCTheo's Typesafe Cult
Created by Jakov on 3/22/2025 in #questions
Buying domain
Haven't used Render, but with Vercel it's very easy to connect a domain to your project. You'll just have to add one or two DNS records to your domain via the Namecheap dashboard. I use the Zoho Mail free plan. You can connect one custom domain and create up to 5 users.
5 replies
TtRPC
Created by Saitama on 3/14/2025 in #❓-help
Type error when following guide TRPC React query: 'lazy' is declared here.
Make sure your server and client are using the exact same version of trpc. That should usually fix errors like this one. (If your versions are already in sync, I unfortunately have no clue what's wrong)
4 replies
TTCTheo's Typesafe Cult
Created by Hex on 3/11/2025 in #questions
Google Docs Clone Tech Stack
In my opinion you don't need to learn another language if you know TypeScript/JS. I'd rather get really good at one language than mediocre at 3 different languages (short-term) (not counting HTML/CSS). Plus with TS/JS it's nice that you can build both frontend and backend with it. Some people might argue that you should use a "dedicated" language for backend stuff, but from my experience you can build solid apps with TS. Plus the ecosystem is huge - there's a package for everything. If you want to land a job, I think the requirements also depend on your country. For example here in Germany, PHP is very popular and many medium-sized companies use it for backends. But as I said, in my opinion TypeScript is a solid choice which can get you a variety of jobs from frontend to backend. If you're decently good at designing / HTML / CSS that's a huge plus. I highly suggest that you build some kind of portfolio using the tech you know - Svelte and TS - and make it open source. That's a nice way to showcase your skills. If you know the principles of any frontend framework, I think one can also land a job at a company which uses a different framework. Because Svelte, React, Vue, etc are very similar, the learning curve should be quite steep.
7 replies
TTCTheo's Typesafe Cult
Created by vikram960 on 3/9/2025 in #questions
which SaaS is used to make this https://docs.uploadthing.com/
Both docs seem to be using a Next.js + Tailwind template https://tailwindcss.com/plus/templates/protocol
4 replies
TtRPC
Created by Hexi on 3/6/2025 in #❓-help
File based structuring, trpc layout
That's not possible as far as I'm aware. You always need to define the structure of your router in code. One approach that comes close to what you're asking is to create nested routers and organize routers and procedures like so:
trpc/
├── router/
│ ├── admin/
│ │ ├── products/
│ │ │ ├── create.handler.ts
│ │ │ ├── edit.handler.ts
│ │ │ └── index.ts
│ │ └── users/
│ │ ├── edit.handler.ts
│ │ └── index.ts
│ ├── public/
│ │ └── cart/
│ │ ├── addItem.handler.ts
│ │ ├── removeItem.handler.ts
│ │ └── index.ts
│ └── index.ts
└── index.ts
trpc/
├── router/
│ ├── admin/
│ │ ├── products/
│ │ │ ├── create.handler.ts
│ │ │ ├── edit.handler.ts
│ │ │ └── index.ts
│ │ └── users/
│ │ ├── edit.handler.ts
│ │ └── index.ts
│ ├── public/
│ │ └── cart/
│ │ ├── addItem.handler.ts
│ │ ├── removeItem.handler.ts
│ │ └── index.ts
│ └── index.ts
└── index.ts
You'll still need to add your procedures to your routers in code
3 replies
TtRPC
Created by Mr. Joker on 3/6/2025 in #❓-help
I'm trying to get type for queries/mutations returned from trpc use hooks, but they are different
This is how I did it:
import { AppRouter } from "../router"
import { TRPCClientErrorLike } from "@trpc/client"
import { UseTRPCQueryResult } from "@trpc/react-query/shared"
import { inferRouterOutputs } from "@trpc/server"

export type TRPCClientError = TRPCClientErrorLike<AppRouter>

export type TRPCUseQueryResult<TData> = UseTRPCQueryResult<
TData,
TRPCClientError
>

export type RouterOutput = inferRouterOutputs<AppRouter>
import { AppRouter } from "../router"
import { TRPCClientErrorLike } from "@trpc/client"
import { UseTRPCQueryResult } from "@trpc/react-query/shared"
import { inferRouterOutputs } from "@trpc/server"

export type TRPCClientError = TRPCClientErrorLike<AppRouter>

export type TRPCUseQueryResult<TData> = UseTRPCQueryResult<
TData,
TRPCClientError
>

export type RouterOutput = inferRouterOutputs<AppRouter>
interface UserContext {
user: TRPCUseQueryResult<RouterOutput["public"]["user"]["me"]>
}

const UserContext = createContext<UserContext | null>(null)

export const UserProvider = ({ children }: { children: React.ReactNode }) => {
const user = trpc.public.user.me.useQuery()

return (
<UserContext.Provider value={{ user }}>
{children}
</UserContext.Provider>
)
}
interface UserContext {
user: TRPCUseQueryResult<RouterOutput["public"]["user"]["me"]>
}

const UserContext = createContext<UserContext | null>(null)

export const UserProvider = ({ children }: { children: React.ReactNode }) => {
const user = trpc.public.user.me.useQuery()

return (
<UserContext.Provider value={{ user }}>
{children}
</UserContext.Provider>
)
}
And here is the same for the new tanstack-react-query integration:
import { AppRouter, RouterOutput } from "..."
import { TRPCClientErrorLike } from "@trpc/client"
import { UseQueryResult } from "@tanstack/react-query"

export { useTRPC, type RouterOutput }
export type TRPCClientError = TRPCClientErrorLike<AppRouter>
export type TRPCUseQueryResult<T> = UseQueryResult<T, TRPCClientError>
import { AppRouter, RouterOutput } from "..."
import { TRPCClientErrorLike } from "@trpc/client"
import { UseQueryResult } from "@tanstack/react-query"

export { useTRPC, type RouterOutput }
export type TRPCClientError = TRPCClientErrorLike<AppRouter>
export type TRPCUseQueryResult<T> = UseQueryResult<T, TRPCClientError>
interface UserContext {
user: TRPCUseQueryResult<RouterOutput["public"]["user"]["me"]>
}

export const UserProvider = ({ children }: { children: React.ReactNode }) => {
const trpc = useTRPC()
const user = useQuery(trpc.public.user.me.queryOptions())

return (
<UserContext.Provider value={{ user }}>
{children}
</UserContext.Provider>
)
}
interface UserContext {
user: TRPCUseQueryResult<RouterOutput["public"]["user"]["me"]>
}

export const UserProvider = ({ children }: { children: React.ReactNode }) => {
const trpc = useTRPC()
const user = useQuery(trpc.public.user.me.queryOptions())

return (
<UserContext.Provider value={{ user }}>
{children}
</UserContext.Provider>
)
}
You should be able to build types for useMutation the same way. I have no examples for that
7 replies
TTCTheo's Typesafe Cult
Created by AmohPrince on 2/27/2025 in #questions
Where the hell do you guys buy your domains
I've been using Namecheap for a few years and been very happy with it. They have great filters for finding TLDs by topic. But in the end I'd say it's mostly personal preference
13 replies
TTCTheo's Typesafe Cult
Created by plyglt on 2/25/2025 in #questions
How do I prefetch trpc serverside and then hydrate the client?
You are probably looking for this https://trpc.io/docs/client/react/server-components
4 replies
TtRPC
Created by Jonathan on 2/21/2025 in #❓-help
Where did useUtils go?
useUtils is just a wrapper around Tanstack Query. See https://trpc.io/docs/client/react/useUtils#helpers The new integration uses native Tanstack Query, removing the wrappers. For your case (the fetch call) I believe you must change your code to:
const trpc = useTRPC()
await queryClient.fetchQuery(trpc.contacts.grid.queryOptions())
const trpc = useTRPC()
await queryClient.fetchQuery(trpc.contacts.grid.queryOptions())
8 replies
TtRPC
Created by Adicss on 2/20/2025 in #❓-help
Upgrading tRPC v10 to v11 in NextJS 15.0.1
tRPC requires TypeScript >=5.7.2
It says it at the top of their docs. But I don't know if this will actually fix it. The upgrade you should do anyways
6 replies
TtRPC
Created by IGMTCrypto on 2/19/2025 in #❓-help
Can I use tRPC on multiple platforms?
6 replies
TtRPC
Created by Szymon on 2/7/2025 in #❓-help
error handling
If you went with this approach and used the tryTo function, I think you could check in the catch block if it's a TRPCClientError and return the message.
if (error instanceof TRPCClientError) {
const message = // get message from error
}
if (error instanceof TRPCClientError) {
const message = // get message from error
}
Haven't tried it tho
9 replies
TtRPC
Created by codecret | Software Engineer on 2/15/2025 in #❓-help
correct way to handle errors run time errors
7 replies
TTCTheo's Typesafe Cult
Created by MrMasolov on 2/15/2025 in #questions
Fetch data in Next app to be available across all app
3 replies
TTCTheo's Typesafe Cult
Created by MrMasolov on 2/15/2025 in #questions
Fetch data in Next app to be available across all app
I would create a React context and place it in the root layout, wrapping the rest of your app. E.g. if you need the current user information, create a UserProvider
"use client"

interface UserContext {
user: any
}

const UserContext = createContext<UserContext | null>(null)

export const UserProvider = ({ children }: { children: React.ReactNode }) => {
const user = trpc.public.user.me.useQuery()
// ^ you could also do a simple fetch inside useEffect and store the user in useState

return (
<UserContext.Provider value={{ user }}>{children}</UserContext.Provider>
)
}

export const useUser = () => {
const context = useContext(UserContext)

if (!context) {
throw new Error("useUser must be used within a UserProvider")
}

return context
}
"use client"

interface UserContext {
user: any
}

const UserContext = createContext<UserContext | null>(null)

export const UserProvider = ({ children }: { children: React.ReactNode }) => {
const user = trpc.public.user.me.useQuery()
// ^ you could also do a simple fetch inside useEffect and store the user in useState

return (
<UserContext.Provider value={{ user }}>{children}</UserContext.Provider>
)
}

export const useUser = () => {
const context = useContext(UserContext)

if (!context) {
throw new Error("useUser must be used within a UserProvider")
}

return context
}
... and then just place it in your root layout.
const RootLayout = ({ children }: { children: React.ReactNode }) => {
return (
<html>
<head></head>
<body>
<UserProvider>
{children}
</UserProvider>
</body>
</html>
)
}

export default RootLayout
const RootLayout = ({ children }: { children: React.ReactNode }) => {
return (
<html>
<head></head>
<body>
<UserProvider>
{children}
</UserProvider>
</body>
</html>
)
}

export default RootLayout
You can then use const { user } = useUser() in any client component.
3 replies
TtRPC
Created by codecret | Software Engineer on 2/13/2025 in #❓-help
invalidate query
You could call refetch after you've awaited your mutation. const { refetch } = trpc.user.getUsers.useQuery()
16 replies
TtRPC
Created by Oung Seik on 2/12/2025 in #❓-help
Can't build NextJS with TRPC vanilla client.
I've had similar issues before and it has to do with path aliases in the tsconfig. I think what's happening is that nextjs tries to resolve @/collections inside of the client app folder and not inside the server folder. Unfortunately I don't have a solution for you, since I work around that by avoiding aliases in my trpc routers, though I agree using path aliases is way cleaner for imports.
4 replies
TtRPC
Created by Szymon on 2/7/2025 in #❓-help
error handling
I guess what you're referring to is the little error popup in Next.js. What I like to do is to wrap my mutation call in a try/catch wrapper function and show a toast in case of errors. Not sure if this is the best solution but it works.
import { toast } from "sonner"

type TryFnHandler = () => any | Promise<any>

interface TryFnOptions<T extends TryFnHandler> {
onSuccess?: (result: Awaited<ReturnType<T>>) => void
onError?: (error: unknown) => void
successMessage?: string | ((result: Awaited<ReturnType<T>>) => string)
errorMessage?: string
}

export async function tryTo<T extends TryFnHandler>(
handler: T,
opts: TryFnOptions<T> = {},
) {
try {
const result = await handler()

if (opts.onSuccess) {
opts.onSuccess(result)
}

if (opts.successMessage) {
if (typeof opts.successMessage === "function") {
toast.success(opts.successMessage(result))
} else {
toast.success(opts.successMessage)
}
}
} catch (error) {
if (opts.onError) {
opts.onError(error)
}

if (opts.errorMessage) {
toast.error(opts.errorMessage)
} else {
const message =
error instanceof Error
? error.message
: "Oh no, something went wrong!"
toast.error(message)
}
}
}
import { toast } from "sonner"

type TryFnHandler = () => any | Promise<any>

interface TryFnOptions<T extends TryFnHandler> {
onSuccess?: (result: Awaited<ReturnType<T>>) => void
onError?: (error: unknown) => void
successMessage?: string | ((result: Awaited<ReturnType<T>>) => string)
errorMessage?: string
}

export async function tryTo<T extends TryFnHandler>(
handler: T,
opts: TryFnOptions<T> = {},
) {
try {
const result = await handler()

if (opts.onSuccess) {
opts.onSuccess(result)
}

if (opts.successMessage) {
if (typeof opts.successMessage === "function") {
toast.success(opts.successMessage(result))
} else {
toast.success(opts.successMessage)
}
}
} catch (error) {
if (opts.onError) {
opts.onError(error)
}

if (opts.errorMessage) {
toast.error(opts.errorMessage)
} else {
const message =
error instanceof Error
? error.message
: "Oh no, something went wrong!"
toast.error(message)
}
}
}
const mutation = trpc.yourHandler.useMutation()

async function doMutation {
await tryTo(async () => {
await mutation.mutateAsync()
})
}
const mutation = trpc.yourHandler.useMutation()

async function doMutation {
await tryTo(async () => {
await mutation.mutateAsync()
})
}
9 replies
TtRPC
Created by Ahmed Eid on 2/6/2025 in #❓-help
How to reset the cache without triggering refetches for none active queries ?
4 replies