T
TanStack2mo ago
generous-apricot

What's the best place to initialise a server-side locale translator function?

I'm using use-intl for my i18n (which is the core library from next-intl. I want to initialise the translator function and inject it into the request context so I can use it in the backend, but have it load the necessary data from user preferences only once.
export const Route = createRootRouteWithContext<MyRouterContext>()({
beforeLoad: async ({ context }) => {
const [
auth,
userPreference,
] = await Promise.all([
context.queryClient.ensureQueryData(authQueryOptions()),
context.queryClient.ensureQueryData(userPreferencesQueryOptions()),
])

const locale = await context.queryClient.ensureQueryData(
localeQueryOptions(userPreference.locale),
)
const translator = createTranslator(locale)

return {
auth,
translator
}
},
shellComponent: RootDocument,
})
export const Route = createRootRouteWithContext<MyRouterContext>()({
beforeLoad: async ({ context }) => {
const [
auth,
userPreference,
] = await Promise.all([
context.queryClient.ensureQueryData(authQueryOptions()),
context.queryClient.ensureQueryData(userPreferencesQueryOptions()),
])

const locale = await context.queryClient.ensureQueryData(
localeQueryOptions(userPreference.locale),
)
const translator = createTranslator(locale)

return {
auth,
translator
}
},
shellComponent: RootDocument,
})
However, I'm getting a ... is not assignable to type '"Function is not serializable" I suppose this is not supported. So, where's the good place to do this?
6 Replies
like-gold
like-gold2mo ago
it depends really where you need that translator only in react?
generous-apricot
generous-apricotOP2mo ago
In places where we can't call hooks. My example was inspired by this repo https://github.com/aaronlin0122/tanstack-boilerplate And here's how they use it https://github.com/search?q=repo%3Aaaronlin0122%2Ftanstack-boilerplate+context.translator&type=code
GitHub
GitHub - aaronlin0122/tanstack-boilerplate: A fully type-safe boile...
A fully type-safe boilerplate with a focus on UX and DX, complete with multiple examples. - aaronlin0122/tanstack-boilerplate
GitHub
Build software better, together
GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.
From An unknown user
From An unknown user
From An unknown user
like-gold
like-gold2mo ago
so inside router lifecycle methods then? would put it into the router context in getRouter()
generous-apricot
generous-apricotOP2mo ago
Something like this?
export const getRouter = async () => {
const rqContext = TanstackQuery.getContext()
const queryClient = rqContext.queryClient
const userPreference = await queryClient.ensureQueryData(userPreferencesQueryOptions())

const locale = await queryClient.ensureQueryData(
localeQueryOptions(userPreference.locale),
)
const translator = createTranslator(locale)

const router = createRouter({
routeTree,
context: { ...rqContext, translator },
defaultPreload: "intent",
Wrap: (props: { children: React.ReactNode }) => {
return <TanstackQuery.Provider {...rqContext}>{props.children}</TanstackQuery.Provider>
},
})

setupRouterSsrQueryIntegration({ router, queryClient: rqContext.queryClient })

return router
}
export const getRouter = async () => {
const rqContext = TanstackQuery.getContext()
const queryClient = rqContext.queryClient
const userPreference = await queryClient.ensureQueryData(userPreferencesQueryOptions())

const locale = await queryClient.ensureQueryData(
localeQueryOptions(userPreference.locale),
)
const translator = createTranslator(locale)

const router = createRouter({
routeTree,
context: { ...rqContext, translator },
defaultPreload: "intent",
Wrap: (props: { children: React.ReactNode }) => {
return <TanstackQuery.Provider {...rqContext}>{props.children}</TanstackQuery.Provider>
},
})

setupRouterSsrQueryIntegration({ router, queryClient: rqContext.queryClient })

return router
}
This should work for my use case. I don't need it at the moment, but is there any option if I want to do the same thing for a specific route only?
like-gold
like-gold2mo ago
it probably should be tweaked so you don't refetch on the client we are working on lifecycle methods that would allow you to this per route without serializing
generous-apricot
generous-apricotOP2mo ago
Thanks! Looking forward to that

Did you find this page helpful?