title | description |
---|---|
Frames.js - fastest way to build Frames |
Frames.js is the react based framework for making frames. Debugger included. |
import { HomePage } from "vocs/components";
<HomePage.Root>
**frames.js** is the fastest way to make Frames. Quickstart GitHub- ⚡️ Local frames debugger
- 🥳 Write Frames using React
- 🔋 Batteries included framework
- 🌴 Tree-shakeable & Lightweight
- 🚀 Library with all the functions
Run one of the commands below based on your preferred package manager and then follow the steps in the terminal.
:::code-group
npm init frames
yarn create frames
pnpm create frames
:::
::::steps
yarn add frames.js
Create a frames
directory in your Next.js app and add the following files:
import { createFrames } from "frames.js/next";
export const frames = createFrames({
basePath: "/frames",
});
/* eslint-disable react/jsx-key */
import { Button } from "frames.js/next";
import { frames } from "./frames";
const handleRequest = frames(async (ctx) => {
return {
image: (
<span>
{ctx.pressedButton
? `I clicked ${ctx.searchParams.value}`
: `Click some button`}
</span>
),
buttons: [
<Button action="post" target={{ query: { value: "Yes" } }}>
Say Yes
</Button>,
<Button action="post" target={{ query: { value: "No" } }}>
Say No
</Button>,
],
};
});
export const GET = handleRequest;
export const POST = handleRequest;
import { fetchMetadata } from "frames.js/next";
export async function generateMetadata() {
return {
title: "My Page",
// ...
other: {
// ...
...(await fetchMetadata(
// provide a full URL to your /frames endpoint
new URL(
"/frames",
process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: "http://localhost:3000"
)
)),
},
};
}
export default function Page() {
return <span>My existing page</span>;
}
::::
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
Or use the hosted Frames debugger. Running locally has the benefits of it working with natively with localhost.
// Page that returns a frame
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),
};
// Route that handles frame actions
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,
});
}
The source code for frames.js is available on GitHub
frames.js is distributed under an MIT License.
We welcome contributions from the community. If you would like to contribute, please open an issue or a pull request.
Feel free to ask any questions on /frames-devs and tag @frames