Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions apps/content/docs/adapters/next.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ oRPC also provides out-of-the-box support for [Server Action](/docs/server-actio

## Server

You can integrate oRPC with Next.js using its [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers).
You set up an oRPC server inside Next.js using its [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers).

::: code-group

Expand Down Expand Up @@ -89,7 +89,7 @@ export const config = {

## Client

Next.js doesnt natively support isomorphic functions, so you need a workaround to make client-side code compatible with SSR. This example uses `globalThis.$headers` as that workaround. Alternatively, you can use React Context like the approach mentioned in [discussions#330](https://github.com/unnoq/orpc/discussions/330#discussioncomment-12727779).
Next.js doesn't natively support isomorphic functions, so you need a workaround to make client-side code compatible with SSR. This example uses `globalThis.$headers` as that workaround. Alternatively, you can use React Context like the approach mentioned in [discussions#330](https://github.com/unnoq/orpc/discussions/330#discussioncomment-12727779).

::: code-group

Expand Down Expand Up @@ -177,7 +177,7 @@ globalThis.$client = createRouterClient(router, {
* For per-request context, use middleware context or pass a function as the initial context.
*/
context: async () => ({
headers: await headers(),
headers: await headers(), // provide headers if initial context required
}),
})
```
Expand Down
74 changes: 73 additions & 1 deletion apps/content/docs/adapters/nuxt.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ description: Use oRPC inside an Nuxt.js project

[Nuxt.js](https://nuxtjs.org/) is a popular Vue.js framework for building server-side applications. It built on top of [Nitro](https://nitro.build/) server a lightweight, high-performance Node.js runtime. For more details, see the [HTTP Adapter](/docs/adapters/http) guide.

## Basic
## Server

You set up an oRPC server inside Nuxt using its [Server Routes](https://nuxt.com/docs/guide/directory-structure/server#server-routes).

::: code-group

Expand Down Expand Up @@ -44,3 +46,73 @@ export { default } from './[...]'
::: info
The `handler` can be any supported oRPC handler, such as [RPCHandler](/docs/rpc-handler), [OpenAPIHandler](/docs/openapi/openapi-handler), or another custom handler.
:::

## Client

To make the oRPC client compatible with SSR, set it up inside a [Nuxt Plugin](https://nuxt.com/docs/guide/directory-structure/plugins).

```ts [plugins/orpc.ts]
export default defineNuxtPlugin(() => {
const event = useRequestEvent()

const link = new RPCLink({
url: `${typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000'}/rpc`,
headers: () => Object.fromEntries(event?.headers ?? []),
})

const client: RouterClient<typeof router> = createORPCClient(link)

return {
provide: {
client,
},
}
})
```
Comment thread
dinwwwh marked this conversation as resolved.

:::info
You can learn more about client setup in [Client-Side Clients](/docs/client/client-side).
:::

## Optimize SSR

To reduce HTTP requests and improve latency during SSR, you can utilize a [Server-Side Client](/docs/client/server-side) during SSR. Below is a quick setup, see [Optimize SSR](/docs/best-practices/optimize-ssr) for more details.

::: code-group

```ts [plugins/orpc.client.ts]
export default defineNuxtPlugin(() => {
const link = new RPCLink({
url: `${window.location.origin}/rpc`,
headers: () => ({}),
})

const client: RouterClient<typeof router> = createORPCClient(link)

return {
provide: {
client,
},
}
})
```

```ts [plugins/orpc.server.ts]
export default defineNuxtPlugin((nuxt) => {
const event = useRequestEvent()

const client = createRouterClient(router, {
context: {
headers: event?.headers, // provide headers if initial context required
},
})

return {
provide: {
client,
},
}
})
```

:::
2 changes: 1 addition & 1 deletion apps/content/docs/adapters/solid-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ globalThis.$client = createRouterClient(router, {
const headers = getRequestEvent()?.request.headers

return {
headers,
headers, // provide headers if initial context required
}
},
})
Expand Down
4 changes: 2 additions & 2 deletions apps/content/docs/adapters/tanstack-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ description: Use oRPC inside a TanStack Start project

## Server

You can integrate oRPC with TanStack Start using its [API Routes](https://tanstack.com/start/latest/docs/framework/react/api-routes).
You set up an oRPC server inside TanStack Start using its [API Routes](https://tanstack.com/start/latest/docs/framework/react/api-routes).

::: code-group

Expand Down Expand Up @@ -97,7 +97,7 @@ const getORPCClient = createIsomorphicFn()
* For per-request context, use middleware context or pass a function as the initial context.
*/
context: async () => ({
headers: getHeaders(),
headers: getHeaders(), // provide headers if initial context required
}),
}))
.client((): RouterClient<typeof router> => {
Expand Down
2 changes: 1 addition & 1 deletion playgrounds/next/src/lib/orpc.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ globalThis.$client = createRouterClient(router, {
* For per-request context, use middleware context or pass a function as the initial context.
*/
context: async () => ({
headers: await headers(),
headers: await headers(), // provide headers if initial context required
}),
})
7 changes: 4 additions & 3 deletions playgrounds/nuxt/components/orpc-mutation.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<script setup lang="ts">
import { useMutation, useQueryClient } from '@tanstack/vue-query'
import { orpc } from '~/lib/orpc'

const { $orpc } = useNuxtApp()

const queryClient = useQueryClient()

const { mutate } = useMutation(orpc.planet.create.mutationOptions({
const { mutate } = useMutation($orpc.planet.create.mutationOptions({
onSuccess() {
queryClient.invalidateQueries({
queryKey: orpc.planet.list.key(),
queryKey: $orpc.planet.list.key(),
})
},
onError(error) {
Expand Down
7 changes: 5 additions & 2 deletions playgrounds/nuxt/components/orpc-query.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
<script setup lang="ts">
import { useInfiniteQuery } from '@tanstack/vue-query'
import { orpc } from '~/lib/orpc'

const query = useInfiniteQuery(orpc.planet.list.infiniteOptions({
const { $orpc } = useNuxtApp()

const query = useInfiniteQuery($orpc.planet.list.infiniteOptions({
input: cursor => ({ cursor, limit: 10 }),
getNextPageParam: lastPage => lastPage.length === 10 ? lastPage.at(-1)?.id : null,
initialPageParam: 0,
}))

await query.suspense()
</script>

<template>
Expand Down
16 changes: 0 additions & 16 deletions playgrounds/nuxt/lib/orpc.ts

This file was deleted.

22 changes: 22 additions & 0 deletions playgrounds/nuxt/plugins/orpc.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { RouterClient } from '@orpc/server'
import type { router } from '~/server/router'
import { createORPCClient } from '@orpc/client'
import { RPCLink } from '@orpc/client/fetch'
import { createTanstackQueryUtils } from '@orpc/tanstack-query'

export default defineNuxtPlugin(() => {
const link = new RPCLink({
url: `${window.location.origin}/rpc`,
headers: () => ({}),
})

const client: RouterClient<typeof router> = createORPCClient(link)

const orpc = createTanstackQueryUtils(client)

return {
provide: {
orpc,
},
}
})
26 changes: 26 additions & 0 deletions playgrounds/nuxt/plugins/orpc.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { createRouterClient } from '@orpc/server'
import { router } from '~/server/router'
import { createTanstackQueryUtils } from '@orpc/tanstack-query'

/**
* This is part of the Optimize SSR setup.
*
* @see {@link https://orpc.unnoq.com/docs/adapters/nuxt#optimize-ssr}
*/
export default defineNuxtPlugin((nuxt) => {
const event = useRequestEvent()

const client = createRouterClient(router, {
context: {
// headers: event?.headers, // provide headers if initial context required
},
})

const orpc = createTanstackQueryUtils(client)

return {
provide: {
orpc,
},
}
})
5 changes: 1 addition & 4 deletions playgrounds/nuxt/server/routes/rpc/[...].ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ const rpcHandler = new RPCHandler(router, {
})

export default defineEventHandler(async (event) => {
const authorization = getHeader(event, 'authorization')
const context = authorization
? { user: { id: 'test', name: 'John Doe', email: 'john@doe.com' } }
: {}
const context = { user: { id: 'test', name: 'John Doe', email: 'john@doe.com' } }

const { matched } = await rpcHandler.handle(event.node.req, event.node.res, {
prefix: '/rpc',
Expand Down
2 changes: 1 addition & 1 deletion playgrounds/solid-start/src/lib/orpc.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ globalThis.$client = createRouterClient(router, {
const headers = getRequestEvent()?.request.headers

return {
headers,
headers, // provide headers if initial context required
}
},
})
2 changes: 1 addition & 1 deletion playgrounds/tanstack-start/src/lib/orpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const getORPCClient = createIsomorphicFn()
* For per-request context, use middleware context or pass a function as the initial context.
*/
context: async () => ({
headers: getHeaders(),
headers: getHeaders(), // provide headers if initial context required
}),
}))
.client((): RouterClient<typeof router> => {
Expand Down