# tRPC on Cloudflare with SST

We are going to build a [tRPC](https://trpc.io/) API, a simple client, and deploy it to Cloudflare using SST.

Before you get started, [create your Cloudflare API token](https://sst.dev/docs/cloudflare/#credentials).

---

## 1. Create a project

Let’s start by creating our app.

```
mkdir my-trpc-app && cd my-trpc-app

npm init -y
```

---

#### Init SST

Now let’s initialize SST in our app.

```
npx sst@latest init

npm install
```

Select the defaults and pick **Cloudflare**. This’ll create a `sst.config.ts` file in your project root.

---

#### Set the Cloudflare credentials

You can save your Cloudflare API token in a `.env` file or just set it directly.

```
export CLOUDFLARE_API_TOKEN=aaaaaaaa_aaaaaaaaaaaa_aaaaaaaa

export CLOUDFLARE_DEFAULT_ACCOUNT_ID=aaaaaaaa_aaaaaaaaaaaa_aaaaaaaa
```

---

## 2. Add the API

Let’s add two Workers; one for our tRPC server and one that’ll be our client. Update your `sst.config.ts`.

```
async run() {

const trpc = new sst.cloudflare.Worker("Trpc", {

url: true,

handler: "index.ts",

});

const client = new sst.cloudflare.Worker("Client", {

url: true,

link: [trpc],

handler: "client.ts",

});

return {

api: trpc.url,

client: client.url,

};

}
```

We are linking the server to our client. This will allow us to access the server in our client.

---

## 3. Create the server

Let’s create our tRPC server. Add the following to `index.ts`.

```
const t = initTRPC.context().create();

const router = t.router({

greet: t.procedure

.input(z.object({ name: z.string() }))

.query(({ input }) => {

return `Hello ${input.name}!`;

}),

});

export type Router = typeof router;

export default {

async fetch(request: Request): Promise<Response> {

return fetchRequestHandler({

router,

req: request,

endpoint: "/",

createContext: (opts) => opts,

});

},

};
```

We are creating a simple method called `greet` that takes a _string_ as an input.

Add the relevant imports.

```
import { z } from "zod";

import { initTRPC } from "@trpc/server";

import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
```

And install the npm packages.

```
npm install zod @trpc/server@next
```

---

## 4. Add the client

Now we’ll connect to our server in our client. Add the following to `client.ts`.

```
export default {

async fetch() {

const client = createTRPCClient<Router>({

links: [

httpBatchLink({

url: "http://localhost/",

fetch(req) {

return Resource.Trpc.fetch(req);

},

}),

],

});

return new Response(

await client.greet.query({

name: "Patrick Star",

}),

);

},

};
```

Add the imports. Notice we are importing the _types_ for our API.

```
import { Resource } from "sst";

import type { Router } from "./index";

import { createTRPCClient, httpBatchLink } from "@trpc/client";
```

Install the client npm package.

```
npm install @trpc/client@next
```

---

#### Start dev mode

Start your app in dev mode.

```
npx sst dev
```

This will give you two URLs.

```
+  Complete

api: https://my-trpc-app-jayair-trpcscript.sst-15d.workers.dev

client: https://my-trpc-app-jayair-clientscript.sst-15d.workers.dev
```

---

#### Test your app

To test our app, hit the client URL.

```
curl https://my-trpc-app-jayair-clientscript.sst-15d.workers.dev
```

This will print out `Hello Patrick Star!`.

---

## 5. Deploy your app

Now let’s deploy your app.

```
npx sst deploy --stage production
```

You can use any stage name here but it’s good to create a new stage for production.
