Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.
Closed
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
55 changes: 55 additions & 0 deletions site/pages/concepts/middleware.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,61 @@ app.frame('/foo', (c) => {/* ... */})
app.frame('/foo/bar', (c) => {/* ... */})
```

### Example: TransactionResponse

You can also write a custom middleware to add additional params to Frog's TransactionResponse (mimics [`Transaction Specs API`](https://warpcast.notion.site/Frame-Transactions-Public-9d9f9f4f527249519a41bd8d16165f73#8235c261091e4499b417e71dd1753e05)).

```tsx twoslash
// @noErrors
import { Frog } from 'frog'

export const app = new Frog()

app.transaction( // [!code focus]
'/mint', // [!code focus]
async (c, next) => { // [!code focus]
await next(); // [!code focus]
const txParams = await c.res.json(); // [!code focus]
txParams.attribution = false; // [!code focus]
c.res = new Response(JSON.stringify(txParams), { // [!code focus]
headers: { // [!code focus]
'Content-Type': 'application/json', // [!code focus]
}, // [!code focus]
}); // [!code focus]
}, // [!code focus]
(c) => {/* ... */} // [!code focus]
); // [!code focus]
Comment on lines +175 to +186
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the provided example is indeed generic but probably not very DX friendly.

I'd rather see attribution flag added (#172), as this looks as more like a feature frog should support internally.

```

### Example: Modifying the FrameResponse

You can write a custom middleware to modify the response to add extra [open-frames metadata](https://github.com/open-frames/standard) to fit your needs.

> Since the Frames Spec is still new (launched on 1/26/24) and hasn't hit a stable v1 yet (current vNext), we don't want to introduce additional standards to Frog that might conflict with or diverge from what the Farcaster team and community has planned. In addition, the vast majority of Frame usage at the moment is via Warpcast (and Farcaster) so we want to make sure Frog serves that main audience first.

```tsx twoslash
// @noErrors
import { Frog } from 'frog'

export const app = new Frog()

app.use(async (c, next) => { // [!code focus]
await next(); // [!code focus]
const isFrame = c.res.headers.get('content-type')?.includes('html'); // [!code focus]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is a better way to check if response is a frame, please update this 🙏

Copy link
Copy Markdown
Collaborator

@dalechyn dalechyn Mar 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe extracting meta tags from head and checking if fc: or frog: are present?

Copy link
Copy Markdown
Contributor Author

@ggomaeng ggomaeng Mar 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but it would also require an additional conditional statement to check if content-type is not application/json in case of transaction responses when used as a global middleware.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true, but for extending meta tags responses maybe it would make sense to add such to FrameResponse itself?

for such middlewares lots of checks have to be performed carefully which is not really dx friendly.

if (isFrame) { // [!code focus]
let html = await c.res.text(); // [!code focus]
const metaTag = '<meta property="of:accepts:xmtp" content="2024-02-01" />'; // [!code focus]
html = html.replace(/(<head>)/i, `$1${metaTag}`); // [!code focus]
c.res = new Response(html, { // [!code focus]
headers: { // [!code focus]
'content-type': 'text/html', // [!code focus]
}, // [!code focus]
}); // [!code focus]
} // [!code focus]
}); // [!code focus]
```


## Community Middleware

Middleware is one of the most powerful pieces of Frog. This section showcases community-built middleware that you can use in your Frog apps.
Expand Down
5 changes: 4 additions & 1 deletion site/pages/reference/frog-transaction-response.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ There are three types of responses:
- [Contract Transaction (`c.contract`)](#contract-transaction-ccontract): Convinience method to **invoke a contract function** (with inferred types & automatic encoding).
- [Raw Transaction (`c.res`)](#raw-transaction-cres): Low-level method to **send raw transaction** (mimics the [Transaction Spec API](https://warpcast.notion.site/Frame-Transactions-Public-Draft-v2-9d9f9f4f527249519a41bd8d16165f73?pvs=4)).

If you want to pass additional parameters to the `TransactionResponse`, refer to the [example of transaction middleware](/concepts/middleware#example-transactionresponse).

```tsx twoslash
// @noErrors
import { Frog, parseEther } from 'frog'
Expand Down Expand Up @@ -375,4 +377,5 @@ app.transaction('/raw-send', (c) => {
}, // [!code focus]
})
})
```
```
import { request } from "http"