Guide: State Management in Frames.js
State in Frames.js is a way for you to store data that you want to use in between frames requests. The frames spec allows up to 4kb of data to be stored in the state object.
Setup
To use state in frames.js, you should declare the initial state in your createFrames
call. If your state type is not declared explicitly it will be derived from the initial state.
import { createFrames } from "frames.js/next";
export type State = {
count: number;
};
export const frames = createFrames<State>({
initialState: {
count: 0,
},
});
Accessing state
You can access the state object in your frame on the ctx
parameter. The initial frame will have the state object with the initial values.
import { frames } from "./frames";
const handler = frames(async (ctx) => {
return {
image: <div tw="flex">Count: {ctx.state.count}</div>,
};
});
export const GET = handler;
export const POST = handler;
Updating state
To update the state, you just include the updated state object in your handler's FrameDefinition
return value.
import { Button } from 'frames.js/next';
import { frames } from "./frames";
const handler = frames(async (ctx) => {
const currentState = ctx.state;
// Update the state
const updatedState = {
...currentState,
count: ctx.pressedButton ? currentState.count + 1 : currentState.count,
};
return {
image: <div tw="flex">Count: {updatedState.count}</div>, ,
buttons: [
<Button action="post">Increment</Button>
],
state: updatedState,
};
});
export const GET = handler;
export const POST = handler;
State protection using a signature
In cases where frame state needs to be trusted, set the stateSigningSecret
option in createFrames
to sign and verify the state signature on each frame request to guarantee its integrity.
import { createFrames } from "@framesjs/next";
export type State = {
count: number;
};
export const frames = createFrames<State>({
initialState: {
count: 0,
},
stateSigningSecret: "my-secret-key",
});