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
1 change: 1 addition & 0 deletions apps/content/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export default defineConfig({
{ text: 'SvelteKit', link: '/docs/integrations/svelte-kit' },
{ text: 'Remix', link: '/docs/integrations/remix' },
{ text: 'SolidStart', link: '/docs/integrations/solid-start' },
{ text: 'React Native', link: '/docs/integrations/react-native' },
],
},
{
Expand Down
32 changes: 32 additions & 0 deletions apps/content/docs/integrations/react-native.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: React Native Integration
description: Seamlessly integrate oRPC with React Native
---

# React Native Integration

[React Native](https://reactnative.dev/) is a framework for building native apps using React.

## Fetch Link

React Native includes a [Fetch API](https://reactnative.dev/docs/network), so you can use oRPC out of the box.

::: warning
However, the Fetch API in React Native has limitations. oRPC features like `File`, `Blob`, and `AsyncIteratorObject` aren't supported. Follow [Support Stream #27741](https://github.com/facebook/react-native/issues/27741) for updates.
:::

```ts
import { RPCLink } from '@orpc/client/fetch'

const link = new RPCLink({
url: 'http://localhost:3000/rpc',
headers: async ({ context }) => ({
'x-api-key': context?.something ?? ''
})
// fetch: <-- polyfill fetch if needed
})
```

::: info
The `link` can be any supported oRPC link, such as [RPCLink](/docs/client/rpc-link), [OpenAPILink](/docs/openapi/client/openapi-link), or another custom link.
:::
6 changes: 5 additions & 1 deletion packages/standard-server-fetch/src/body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { generateContentDisposition, getFilenameFromContentDisposition } from '@
import { toEventIterator, toEventStream } from './event-iterator'

export async function toStandardBody(re: Request | Response): Promise<StandardBody> {
if (!re.body) {
/**
* In native environments like React Native, the body may be `undefined` due to lack of streaming support.
* Therefore, we explicitly check for `null` to indicate an intentionally empty body.
*/
if (re.body === null) {
return undefined
}

Expand Down