Skip to content

Commit dd94d9d

Browse files
davidfurlongstephancill
authored andcommitted
chore: add docs guides
1 parent 54855e2 commit dd94d9d

20 files changed

+523
-54
lines changed

docs/pages/guides/caching.mdx

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
title: "Caching"
3+
description: ""
4+
---
5+
6+
You can set the caching policy of your frames by defining the `Cache-Control` headers of your responses
7+
8+
```tsx
9+
// ...
10+
const handleRequest = frames(async ({ message }) => {
11+
return {
12+
// ...
13+
headers: {
14+
// Max cache age of 5 seconds
15+
"Cache-Control": "max-age=5",
16+
},
17+
};
18+
});
19+
```

docs/pages/guides/create-frame.mdx

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
title: "Guide: Display Frames in your app"
3+
description: "Frames.js is the react based framework for making frames. Debugger included."
4+
---
5+
6+
# Quickstart Guide: Create your first Frame
7+
8+
This guide shows you how to add frames rendering to your next.js + tailwind app using frames.js.
9+
10+
## Steps
11+
12+
1. Create a new repo
13+
14+
`npx create-next-app@latest my-project --ts --eslint --tailwind --app`
15+
16+
`cd my-project`
17+
18+
`yarn add frames.js`
19+
20+
`yarn install`
21+
22+
2. Create your Frames app
23+
24+
```tsx filename="// ./app/frames/route.tsx"
25+
// ./app/frames/route.tsx
26+
import { createFrames, Button } from "frames.js/next";
27+
28+
const frames = createFrames();
29+
const handleRequest = frames(async ({ pressedButton }) => {
30+
return {
31+
image: (
32+
<span>
33+
{pressedButton
34+
? `I clicked ${pressedButton.state}`
35+
: `Click some button`}
36+
</span>
37+
),
38+
buttons: [
39+
<Button action="post" state="Yes">
40+
Say Yes
41+
</Button>,
42+
<Button action="post" state="No">
43+
Say No
44+
</Button>,
45+
],
46+
};
47+
});
48+
49+
export const GET = handleRequest;
50+
export const POST = handleRequest;
51+
```
52+
53+
3. If you have an existing page, render Frames in your metadata
54+
55+
```tsx filename="// ./app/page.tsx"
56+
// ./app/page.tsx
57+
import { fetchMetadata } from "frames.js/next";
58+
59+
export async function generateMetadata() {
60+
return {
61+
title: "My Page",
62+
// provide a full URL to your /frames endpoint
63+
...(await fetchMetadata(
64+
new URL("/frames", process.env.VERCEL_URL || "http://localhost:3000")
65+
)),
66+
};
67+
}
68+
69+
export default function Page() {
70+
return <span>My existing page</span>;
71+
}
72+
```
73+
74+
4. Run `yarn run dev`
75+
76+
5. Done! 🎉

docs/pages/guides/debugger.mdx

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: "Local Debugging"
3+
description: "Build and test your frames with confidence"
4+
---
5+
6+
# Local Debugging of your Frames
7+
8+
![](/frames/frame2.png)
9+
10+
The frames.js debugger comes inside the frames.js starter repos and will run automatically when you run your code.
11+
By default it runs on port 3010, at [http://localhost:3010](http://localhost:3010/?url=http%3A%2F%2Flocalhost%3A3000%2F).
12+
13+
Features
14+
- fully interactive frames
15+
- connect wallet + transactions
16+
- performance analysis
17+
- frame validations
18+
- jump between Frames
19+
- inspect state
20+
- mock hub states
21+
- impersonate a user, or login with a real farcaster signer
22+
23+
## Local Debugger CLI
24+
25+
You can install and run the frames.js debugger independently of your frame, including for frames.js that don't use frames.js via
26+
27+
`npm install -g @frames.js/debugger`
28+
29+
`frames`
30+
31+
## Hosted Debugger
32+
33+
We've provided a [hosted version](https://debugger.framesjs.org/?url=https%3A%2F%2Fframesjs.org) of the debugger for convenience. Note it won't work with localhost urls without a service like `ngrok`, which is why we recommend running a local debugger.

docs/pages/guides/deployment.mdx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
title: "Deployments"
3+
description: "A guide on shipping your frames.js frame to production"
4+
---
5+
6+
# Shipping your Frame to production
7+
8+
Frames.js works in most javascript frameworks or libraries, and should work out of the box with whereever you would normally deploy those.
9+
10+
We suggest deploying your frames to Vercel, but Cloudflare workers, Docker, AWS or other platforms are compatible.
11+
12+
## Vercel Deployments
13+
14+
Run the `vercel` command-line tool from your frame's folder to deploy your frame to vercel.

docs/pages/guides/display-frames.mdx

+63-48
Original file line numberDiff line numberDiff line change
@@ -19,72 +19,82 @@ This guide shows you how to add frames rendering to your next.js + tailwind app
1919

2020
`yarn install`
2121

22-
2. Create your Frames app
23-
22+
2. Add proxies for routing frame requests via your backend for privacy + preventing CORS issues
2423
```tsx filename="// ./app/frames/route.tsx"
2524
// ./app/frames/route.tsx
26-
import { createFrames, Button } from "frames.js/next";
27-
28-
const frames = createFrames();
29-
const handleRequest = frames(async ({ clickedButton }) => {
30-
return {
31-
image: (
32-
<span>
33-
{clickedButton
34-
? `I clicked ${clickedButton.state}`
35-
: `Click some button`}
36-
</span>
37-
),
38-
buttons: [
39-
<Button action="post" state="Yes">
40-
Say Yes
41-
</Button>,
42-
<Button action="post" state="No">
43-
Say No
44-
</Button>,
45-
],
46-
};
47-
});
48-
49-
export const GET = handleRequest;
50-
export const POST = handleRequest;
25+
export { GET, POST } from "frames.js/render/next";
5126
```
5227

53-
3. If you have an existing page, render Frames in your metadata
28+
3. Add the renderer to your page
5429

5530
```tsx filename="// ./app/page.tsx"
5631
// ./app/page.tsx
57-
import { fetchMetadata } from "frames.js/next";
58-
59-
export async function generateMetadata() {
60-
return {
61-
title: "My Page",
62-
// provide a full URL to your /frames endpoint
63-
...(await fetchMetadata(
64-
new URL("/frames", process.env.VERCEL_URL || "http://localhost:3000")
65-
)),
66-
};
67-
}
32+
"use client";
33+
import {
34+
FrameUI,
35+
fallbackFrameContext,
36+
FrameContext,
37+
} from "frames.js/render";
38+
import { signFrameAction, FarcasterSigner } from 'frames.js/render/farcaster'
39+
import { FrameImageNext } from "frames.js/render/next";
40+
import { FrameButton } from "frames.js";
41+
import { useFrame } from "frames.js/render/use-frame";
6842

6943
export default function Page() {
70-
return <span>My existing page</span>;
44+
// TODO: replace with your farcaster signer
45+
const farcasterSigner: FarcasterSigner = {
46+
fid: 1,
47+
status: 'approved',
48+
publicKey:
49+
"0x00000000000000000000000000000000000000000000000000000000000000000",
50+
privateKey:
51+
"0x00000000000000000000000000000000000000000000000000000000000000000",
52+
};
53+
54+
const frameState = useFrame({
55+
// replace with your frame url
56+
homeframeUrl:
57+
"https://fc-polls.vercel.app/polls/73c6efda-bae7-4d46-8f36-3bb3b8377448",
58+
// corresponds to the name of the route for POST in step 3
59+
frameActionProxy: "/frames",
60+
// corresponds to the name of the route for GET in step 3
61+
frameGetProxy: "/frames",
62+
frameContext: fallbackFrameContext,
63+
// map to your identity if you have one
64+
signerState: {
65+
hasSigner: true,
66+
signer: farcasterSigner,
67+
onSignerlessFramePress: () => {
68+
// Implement me
69+
alert("A frame button was pressed without a signer. Perhaps you want to prompt a login");
70+
},
71+
signFrameAction: signFrameAction,
72+
},
73+
});
74+
75+
return (
76+
<div className="w-[400px]">
77+
<FrameUI frameState={frameState} theme={{}} FrameImage={FrameImageNext} />
78+
</div>
79+
);
7180
}
81+
7282
```
7383

7484
4. In order for the styles to work, your project should have tailwind set up as well as the tailwind.config.js rule
7585

7686
```tsx filename="// tailwind.config.js"
7787
// tailwind.config.js
7888
const config = {
79-
// ...
80-
content: [
81-
"./app/*.{ts,tsx,js,css}",
82-
"./app/**/*.{ts,tsx,js,css}",
83-
"./node_modules/frames.js/dist/render/next/*.{ts,tsx,js,css}",
84-
"./node_modules/frames.js/dist/render/*.{ts,tsx,js,css}",
8589
// ...
86-
],
87-
};
90+
content: [
91+
"./app/*.{ts,tsx,js,css}",
92+
"./app/**/*.{ts,tsx,js,css}",
93+
"./node_modules/frames.js/dist/render/next/*.{ts,tsx,js,css}",
94+
"./node_modules/frames.js/dist/render/*.{ts,tsx,js,css}",
95+
// ...
96+
]
97+
}
8898
```
8999

90100
5. Allow images from any domain
@@ -106,3 +116,8 @@ const nextConfig = {
106116
6. Run `yarn run dev`
107117

108118
7. Done! 🎉
119+
120+
121+
### Optional
122+
123+
If needed, you can implement `FrameUI` yourself, using the [FrameUI](https://github.com/framesjs/frames.js/blob/main/packages/frames.js/src/render/frame-ui.tsx) component as a template
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
title: "Image Generation"
3+
description: "A guide on how to use images inside of frames"
4+
---
5+
6+
# Images
7+
8+
## Static Images
9+
10+
```tsx
11+
// ...
12+
const handleRequest = frames(async ({ message }) => {
13+
return {
14+
// ...
15+
image: "https://picsum.photos/seed/frames.js/1146/600",
16+
};
17+
});
18+
```
19+
20+
## Dynamic Image generation
21+
22+
You can define a dynamic image by passing in a `JSX` element to `image` property. This uses [@vercel/og](https://vercel.com/docs/functions/og-image-generation) library under the hood, which includes a syntax for writing [tailwind CSS](https://tailwindcss.com/). You can pass in options for `@vercel/og` via the `imageOptions` property.
23+
There are certain constraints around dynamic images that you should be aware of - firstly, they can be slow, affecting the UX.
24+
Secondly, dynamic images have a size limit of 256kB, which can easily be crossed if you use an existing image inside of the dynamic image.
25+
26+
```tsx
27+
// ...
28+
const handleRequest = frames(async ({ message }) => {
29+
return {
30+
// ...
31+
image: (
32+
<div tw="bg-purple-800 text-white w-full h-full justify-center items-center flex">
33+
This is rendered as an image
34+
</div>
35+
),
36+
imageOptions: {
37+
// ...
38+
}
39+
};
40+
});
41+
```

docs/pages/guides/middleware.mdx

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
title: "Middleware"
3+
description: ""
4+
---
5+
6+
Frames.js uses middleware to extend the functionality of Frames, bringing in data from API providers, verifying frame actions and adding Open Frames support.
7+
8+
You can use middleware for all your frames by passing in middleware via `createFrames({ middleware: [...] })`.

docs/pages/guides/migration-guide.mdx

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
title: "Migrating Guide"
3+
description: "Update your frames.js version, pain free."
4+
---
5+
6+
# Migration Guides
7+
8+
## 0.9.x Breaking changes
9+
10+
### Version 0.9 changes many APIs and decouples frames.js to no longer require next.js
11+
12+
- Removes `useReducer` and state handling from computing from previous state to buttons defining the next state directly
13+
- Removes the need for `useReducer`, instead providing context via the `frames` function and middleware
14+
- Internal URL query parameters have changed
15+
- Imports have changed slightly
16+
- Routes now use JSX, so you may need to rename `route.ts` to `route.tsx`
17+
- For next.js app router, metadata is done via the `generateMetadata` function instead of rendering meta tags in the body
18+
- Replacing `<FrameContainer>`, JSX is now done within a `JSON` object return

0 commit comments

Comments
 (0)