Frog.frame Context
The c
object is the parameter of the route handlers. It contains context about the current frame.
import { Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
return c.res({/* ... */})
})
buttonIndex
- Type:
number
The index of the button that was previously clicked.
For example, if the user clicked "Banana"
, then buttonIndex
will be 2
.
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
const { buttonIndex } = c
return c.res({
image: (
<div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
Selected: {buttonIndex}
</div>
),
intents: [
<Button value="apple">Apple</Button>,
<Button value="banana">Banana</Button>,
<Button value="mango">Mango</Button>
]
})
})
buttonValue
- Type:
string
The value of the button that was previously clicked.
For example, if the user clicked "Banana"
, then buttonValue
will be "banana"
.
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
const { buttonValue } = c
return c.res({
image: (
<div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
Selected: {buttonValue}
</div>
),
intents: [
<Button value="apple">Apple</Button>,
<Button value="banana">Banana</Button>,
<Button value="mango">Mango</Button>
]
})
})
deriveState
- Type:
(state: State) => void
Derives new state from the state of the previous frame.
Internally uses Immers's produce
function to create a draft of the state, and then applies the changes to the state.
import { Button, Frog } from 'frog'
type State = {
values: string[]
}
export const app = new Frog<{ State: State }>({
initialState: {
values: []
}
})
app.frame('/', (c) => {
const { buttonValue, deriveState } = c
const state = deriveState(previousState => {
if (buttonValue) previousState.values.push(buttonValue)
})
return c.res({
image: (
<div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
{state.values.map(value => <div>{value}</div>)}
</div>
),
intents: [
<Button value="apple">Apple</Button>,
<Button value="banana">Banana</Button>,
<Button value="mango">Mango</Button>,
]
})
})
error
- Type:
(error: BaseError) => TypedResponse
Error response.
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
return c.error({/* ... */})
})
frameData
- Type:
FrameData
Data from the frame that was passed via the POST
body from a Farcaster Client. See more.
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
const { frameData } = c
const { castId, fid, messageHash, network, timestamp, url } = frameData
return c.res({/* ... */})
})
initialPath
- Type:
string
Initial/start path of the frame set.
If the user clicks <Button.Reset>
, they will be directed to this URL.
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
const { initialPath } = c
return c.res({/* ... */})
})
inputText
- Type:
string
The value of the input that was previously interacted with.
For example, if the user typed "Banana"
, then inputText
will be "Banana"
.
import { Button, Frog, TextInput } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
const { inputText } = c
return c.res({
image: (
<div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
Selected: {inputText}
</div>
),
intents: [
<TextInput placeholder="Type your fruit..." />,
<Button>Submit</Button>,
]
})
})
previousButtonValues
- Type:
string[]
The data of the previous intents.
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
return c.res({
action: '/result',
image: (
<div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
Select your fruit
</div>
),
intents: [
<Button value="apple">Apple</Button>,
<Button value="banana">Banana</Button>,
<Button value="mango">Mango</Button>
]
})
})
app.frame('/result', (c) => {
const { buttonValue, previousButtonValues } = c
console.log(previousButtonValues)
['apple', 'banana', 'mango'] return c.res({ image: (
<div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
Selected: {buttonValue}
</div>
),
intents: [
<Button.Reset>Reset</Button.Reset>,
]
})
})
previousState
- Type:
State
The state of the previous frame.
import { Button, Frog } from 'frog'
type State = {
values: string[]
}
export const app = new Frog<{ State: State }>({
initialState: {
values: []
}
})
app.frame('/', (c) => {
const { buttonValue, deriveState, previousState } = c
const state = deriveState(previousState => {
if (buttonValue) previousState.values.push(buttonValue)
})
return c.res({
image: (
<div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
{values.map(value => <div>{value}</div>)}
</div>
),
intents: [
<Button value="apple">Apple</Button>,
<Button value="banana">Banana</Button>,
<Button value="mango">Mango</Button>,
]
})
})
req
- Type:
Request
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
const { req } = c
return c.res({/* ... */})
})
res
- Type:
(response: FrameResponse) => FrameResponse
The frame response.
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
return c.res({/* ... */})
})
status
- Type:
"initial" | "redirect" | "response"
Status of the frame in the frame lifecycle.
initial
- The frame has not yet been interacted with.redirect
- The frame interaction is a redirect (button of type'post_redirect'
).response
- The frame has been interacted with (user presses button).
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
const { status } = c
return c.res({/* ... */})
})
transactionId
- Type:
string | undefined
The chain-specific transaction ID. Defined at the action
frame of transaction
route.
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
return c.res({
action: '/finish',
image: (
<div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
Perform a transaction
</div>
),
intents: [
<TextInput placeholder="Value (ETH)" />,
<Button.Transaction target="/send-ether">Send Ether</Button.Transaction>,
]
})
})
app.frame('/finish', (c) => {
const { transactionId } = c
return c.res({
image: (
<div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
Transaction ID: {transactionId}
</div>
)
})
})
var
- Type:
HonoContext['var']
Extract a context value that was previously set via set
in Middleware.
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.use(async (c, next) => {
c.set('message', 'Frog is cool!!')
await next()
})
app.frame('/', (c) => {
const message = c.var.message
return c.res({/* ... */})
})
verified
- Type:
boolean
Whether or not the frameData
(and buttonIndex
, buttonValue
, inputText
) was verified by the Farcaster Hub API.
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
const { verified } = c
return c.res({/* ... */})
})
url
- Type:
string
URL of the frame.
import { Button, Frog } from 'frog'
export const app = new Frog({ title: 'Frog Frame' })
app.frame('/', (c) => {
const { url } = c
return c.res({/* ... */})
})