Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Zizzamia/a-frame-in-100-lines
Farcaster Frames in less than 100 lines, and ready to be deployed to Vercel.
https://github.com/Zizzamia/a-frame-in-100-lines
Last synced: 25 days ago
JSON representation
Farcaster Frames in less than 100 lines, and ready to be deployed to Vercel.
- Host: GitHub
- URL: https://github.com/Zizzamia/a-frame-in-100-lines
- Owner: Zizzamia
- License: mit
- Created: 2024-01-28T08:16:21.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2024-08-10T21:23:32.000Z (4 months ago)
- Last Synced: 2024-08-10T22:30:37.057Z (4 months ago)
- Language: TypeScript
- Homepage: https://onchainkit.xyz
- Size: 3.85 MB
- Stars: 219
- Watchers: 4
- Forks: 254
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-frames - Next JS
- awesome-farcaster-dev - `a-frame-in-100-lines`
- awesome-farcaster-dev - `a-frame-in-100-lines`
README
# A Frame in 100 lines (or less)
Farcaster Frames in less than 100 lines, and ready to be deployed to Vercel.
To test a **deployed** Frame, use: https://warpcast.com/~/developers/frames.
To test a **localhost** Frame, use: [Framegear](https://onchainkit.xyz/frame/framegear).
A simple tool that allows you to run and test your frames locally:- without publishing
- without casting
- without spending warpsAnd let us know what you build by either mentioning @zizzamia on [Warpcast](https://warpcast.com/zizzamia) or [X](https://twitter.com/Zizzamia).
Have fun! ⛵️
## App Routing files
- app/
- [config.ts](https://github.com/Zizzamia/a-frame-in-100-lines?tab=readme-ov-file#appconfigts)
- [layout.tsx](https://github.com/Zizzamia/a-frame-in-100-lines?tab=readme-ov-file#applayouttsx)
- [page.tsx](https://github.com/Zizzamia/a-frame-in-100-lines?tab=readme-ov-file#apppagetsx)
- api/
- frame/
- [route.ts](https://github.com/Zizzamia/a-frame-in-100-lines?tab=readme-ov-file#appapiframeroutets)
### `app/page.tsx`
```tsx
import { getFrameMetadata } from '@coinbase/onchainkit/frame';
import type { Metadata } from 'next';
import { NEXT_PUBLIC_URL } from './config';const frameMetadata = getFrameMetadata({
buttons: [
{
label: 'Story time!',
},
{
action: 'link',
label: 'Link to Google',
target: 'https://www.google.com',
},
{
label: 'Redirect to pictures',
action: 'post_redirect',
},
],
image: {
src: `${NEXT_PUBLIC_URL}/park-3.png`,
aspectRatio: '1:1',
},
input: {
text: 'Tell me a boat story',
},
postUrl: `${NEXT_PUBLIC_URL}/api/frame`,
});export const metadata: Metadata = {
title: 'zizzamia.xyz',
description: 'LFG',
openGraph: {
title: 'zizzamia.xyz',
description: 'LFG',
images: [`${NEXT_PUBLIC_URL}/park-1.png`],
},
other: {
...frameMetadata,
},
};export default function Page() {
return (
<>
zizzamia.xyz
>
);
}
```### `app/layout.tsx`
```tsx
export const viewport = {
width: 'device-width',
initialScale: 1.0,
};export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```### `app/config.ts`
```ts
export const NEXT_PUBLIC_URL = 'https://zizzamia.xyz';
```### `app/api/frame/route.ts`
```ts
import { FrameRequest, getFrameMessage, getFrameHtmlResponse } from '@coinbase/onchainkit/frame';
import { NextRequest, NextResponse } from 'next/server';
import { NEXT_PUBLIC_URL } from '../../config';async function getResponse(req: NextRequest): Promise {
let accountAddress: string | undefined = '';
let text: string | undefined = '';const body: FrameRequest = await req.json();
const { isValid, message } = await getFrameMessage(body, { neynarApiKey: 'NEYNAR_ONCHAIN_KIT' });if (isValid) {
accountAddress = message.interactor.verified_accounts[0];
}if (message?.input) {
text = message.input;
}if (message?.button === 3) {
return NextResponse.redirect(
'https://www.google.com/search?q=cute+dog+pictures&tbm=isch&source=lnms',
{ status: 302 },
);
}return new NextResponse(
getFrameHtmlResponse({
buttons: [
{
label: `🌲 ${text} 🌲`,
},
],
image: {
src: `${NEXT_PUBLIC_URL}/park-1.png`,
},
postUrl: `${NEXT_PUBLIC_URL}/api/frame`,
}),
);
}export async function POST(req: NextRequest): Promise {
return getResponse(req);
}export const dynamic = 'force-dynamic';
```
## Resources
- [Official Farcaster Frames documentation](https://docs.farcaster.xyz/learn/what-is-farcaster/frames)
- [Official Farcaster Frame specification](https://docs.farcaster.xyz/reference/frames/spec)
- [OnchainKit documentation](https://onchainkit.xyz)
## Community ☁️ 🌁 ☁️
Check out the following places for more OnchainKit-related content:
- Follow @zizzamia ([X](https://twitter.com/zizzamia), [Farcaster](https://warpcast.com/zizzamia)) for project updates
- Join the discussions on our [OnchainKit warpcast channel](https://warpcast.com/~/channel/onchainkit)## Authors
- [@zizzamia](https://github.com/zizzamia.png) ([X](https://twitter.com/Zizzamia))
- [@cnasc](https://github.com/cnasc.png) ([warpcast](https://warpcast.com/cnasc))## License
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details