Skip to content

Button

In order to render buttons you should use our <Button> component. Frames.js supports the following button types:

Post Button

import { Button } from "frames.js/core";
 
<Button action="post">Click me</Button>;

This button sends a request to a URL on which it was rendered. If you want to navigate to different route in your app, you can use target prop which should be set to relative path.

<Button action="post" target="/next-route">
  Click me
</Button>

The target path will be resolved relatively to current URL.

Passing state between frames

<Button
  action="post"
  target={{ query: { foo: "bar" }, pathname: "/next-route" }}
>
  Click me
</Button>

The state will be available in the frame handler via ctx.searchParams e.g.

ctx.searchParams.foo; // bar

Post Redirect Button

Post redirect button is a special kind of post button that when users clicks the button, first a message is sent to frames handler and then it is expected that handler will redirect the user to a different route using redirect call.

It accepts same props as post button.

import { Button } from "frames.js/core";
 
<Button
  action="post_redirect"
  target={{ query: { foo: "bar" }, pathname: "/next-route" }}
>
  Click me
</Button>;

Link Button

Link button navigates to external URL when clicked.

import { Button } from "frames.js/core";
 
<Button action="link" target="https://google.com">
  Click me
</Button>;

Mint Button

Mint button creates a new token when clicked.

import { Button } from "frames.js/core";
import { getTokenUrl } from "frames.js";
 
<Button
  action="mint"
  target={getTokenUrl({
    address: "0x8f5ed2503b71e8492badd21d5aaef75d65ac0042",
    chain: zora,
    tokenId: "3",
  })}
>
  Mint
</Button>;

Tx Button

Tx button requests transaction data from target when clicked, and send the transaction ID to the frame's post_url or the button's post_url if it is set.

import { Button } from "frames.js/core";
 
<Button action="tx" target="/txdata" post_url="/tx-success">
  Buy storage
</Button>;

Transaction data

The endpoint specified in target should return a JSON object with the following structure:

type TransactionTargetResponse {
  chainId: string;
  method: "eth_sendTransaction";
  attribution?: boolean;
  params: EthSendTransactionParams;
}
type EthSendTransactionParams {
  abi: Abi | [];
  to: Hex;
  value?: string;
  data?: Hex;
}

Transaction Success

If the transaction is successful, the frame will send a POST request to the URL specified in post_url or the frame post_url. This can be handled by the frame to show a success message or redirect the user to a different page.

route.tsx
import { Button } from "frames.js/next";
import { createFrames } from "frames.js/next";
 
const export frames = createFrames()
 
export const GET = frames(async (ctx) => {
  return {
    image: (
      <div tw="flex">
        Execute transaction
      </div>
    ),
    buttons: [
      <Button action="tx" target="/txdata" post_url="/tx-success">
        Execute
      </Button>,
    ],
  };
})
// /tx-success/route.tsx
 
import { frames } from ../route.tsx";
 
const handleRequest = frames(async (ctx) => {
  if (message?.transactionId) {
    return {
      image: (
        <div tw="flex">
          Transaction submitted! {ctx.message.transactionId}
        </div>
      ),
      buttons: [
        <Button
          action="link"
          target={`https://www.onceupon.gg/tx/${ctx.message.transactionId}`}
        >
          View on block explorer
        </Button>,
      ],
    };
  }
});