@sekmet/frames.js
v0.8.2
Published
frames.js is a TypeScript library and framework for writing and testing Farcaster Frames.
Downloads
4
Readme
frames.js
frames.js is a TypeScript library and framework for writing and testing Farcaster Frames.
Features
- ⚡️ Local frames debugger
- 🥳 Write Frames using React
- 🔋 Batteries included framework
- 🌴 Tree-shakeable & Lightweight
- 🚀 Library with all the functions
Documentation
Look at our documentation to learn more about frames.js.
Installation
npm install frames.js
yarn add frames.js
Quick Start
Clone the frames.js starter template (with local debugger)
Run to clone the starter into a new folder called framesjs-starter
npx degit github:framesjs/frames.js/examples/framesjs-starter#main framesjs-starter
Alternatively, Start with frames.js in Next.js in two copy-pastes
// ./app/page.tsx
import {
FrameContainer,
FrameImage,
FrameButton,
useFramesReducer,
getPreviousFrame,
validateActionSignature,
FrameInput,
} from "frames.js/next/server";
const reducer = (state, action) => ({ count: state.count + 1 });
export default async function Home(props) {
const previousFrame = getPreviousFrame(props.searchParams);
await validateActionSignature(previousFrame.postBody);
const [state, dispatch] = useFramesReducer(
reducer,
{ count: 0 },
previousFrame
);
return (
<FrameContainer
postUrl="/frames"
state={state}
previousFrame={previousFrame}
>
<FrameImage src="https://picsum.photos/seed/frames.js/1146/600" />
<FrameButton onClick={dispatch}>{state.count}</FrameButton>
</FrameContainer>
);
}
// ./app/frames/route.ts
export { POST } from "frames.js/next/server";
Local fully interactive Debugger & Frame validation
Or use the hosted Frames debugger. Running locally has the benefits of it working with localhost.
Prefer to not use JSX?
Use frames.js in Next.js using helper functions
// page that renders a frame
// ./app/page.tsx
import { Frame, getFrameFlattened } from "frames.js";
import type { Metadata } from "next";
// Declare the frame
const initialFrame: Frame = {
image: "https://picsum.photos/seed/frames.js/1146/600",
version: "vNext",
buttons: [
{
label: "Random image",
},
],
postUrl: `${process.env.NEXT_PUBLIC_HOST}/frames`,
};
// Export Next.js metadata
export const metadata: Metadata = {
title: "Random Image Frame",
description: "This is an example of a simple frame using frames.js",
openGraph: {
images: [
{
url: "https://picsum.photos/seed/frames.js/600",
},
],
},
other: getFrameFlattened(initialFrame),
};
// handle frame actions
// ./app/frames/route.ts
import { getFrameHtml, validateFrameMessage } from "frames.js";
import { NextRequest } from "next/server";
export async function POST(request: NextRequest) {
const body = await request.json();
// Parse and validate the frame message
const { isValid, message } = await validateFrameMessage(body);
if (!isValid || !message) {
return new Response("Invalid message", { status: 400 });
}
const randomInt = Math.floor(Math.random() * 100);
const imageUrlBase = `https://picsum.photos/seed/${randomInt}`;
// Use the frame message to build the frame
const frame = {
version: "vNext",
image: `${imageUrlBase}/1146/600`,
buttons: [
{
label: `Next (pressed by ${message.data.fid})`,
},
],
ogImage: `${imageUrlBase}/600`,
postUrl: `${process.env.NEXT_PUBLIC_HOST}/frames`,
};
// Return the frame as HTML
const html = getFrameHtml(frame);
return new Response(html, {
headers: {
"Content-Type": "text/html",
},
status: 200,
});
}
License
Distributed under an MIT License. See LICENSE for more information.
Community
Check out the following places for more Frames-related content:
- Join the /frames-dev channel on Farcaster to ask questions
- Follow Frames.js & team (@df and @stephancill) on Farcaster for updates
- Star frames.js on GitHub to show your support and keep track of updates
- Browse the awesome-frames list of awesome Frames projects and resources