From dea4cb6f9779f6eba2e5c147e8bab14f0c466e6c Mon Sep 17 00:00:00 2001 From: unnoq Date: Tue, 22 Apr 2025 10:16:46 +0700 Subject: [PATCH] feat(standard-server): support React Native by explicitly checking for null body By explicitly check for `null` to indicate an intentionally empty body instead of relying on a truthy body check. --- apps/content/.vitepress/config.ts | 1 + .../content/docs/integrations/react-native.md | 32 +++++++++++++++++++ packages/standard-server-fetch/src/body.ts | 6 +++- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 apps/content/docs/integrations/react-native.md diff --git a/apps/content/.vitepress/config.ts b/apps/content/.vitepress/config.ts index da4011a30..61ced3b9b 100644 --- a/apps/content/.vitepress/config.ts +++ b/apps/content/.vitepress/config.ts @@ -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' }, ], }, { diff --git a/apps/content/docs/integrations/react-native.md b/apps/content/docs/integrations/react-native.md new file mode 100644 index 000000000..05b858b2a --- /dev/null +++ b/apps/content/docs/integrations/react-native.md @@ -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. +::: diff --git a/packages/standard-server-fetch/src/body.ts b/packages/standard-server-fetch/src/body.ts index e1efcc579..08223ec22 100644 --- a/packages/standard-server-fetch/src/body.ts +++ b/packages/standard-server-fetch/src/body.ts @@ -5,7 +5,11 @@ import { generateContentDisposition, getFilenameFromContentDisposition } from '@ import { toEventIterator, toEventStream } from './event-iterator' export async function toStandardBody(re: Request | Response): Promise { - 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 }