{"id":13776419,"url":"https://github.com/Zizzamia/a-frame-in-100-lines","last_synced_at":"2025-05-11T10:31:03.542Z","repository":{"id":219550457,"uuid":"749319852","full_name":"Zizzamia/a-frame-in-100-lines","owner":"Zizzamia","description":"Farcaster Frames in less than 100 lines, and ready to be deployed to Vercel.","archived":false,"fork":false,"pushed_at":"2024-08-10T21:23:32.000Z","size":4040,"stargazers_count":237,"open_issues_count":5,"forks_count":259,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-05T00:09:24.334Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://onchainkit.xyz","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Zizzamia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-28T08:16:21.000Z","updated_at":"2025-04-04T21:10:06.000Z","dependencies_parsed_at":"2024-04-18T18:44:14.169Z","dependency_job_id":"7195f3dd-86c7-47b4-a8a9-25449b5925e9","html_url":"https://github.com/Zizzamia/a-frame-in-100-lines","commit_stats":null,"previous_names":["zizzamia/a-frame-in-100-lines"],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zizzamia%2Fa-frame-in-100-lines","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zizzamia%2Fa-frame-in-100-lines/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zizzamia%2Fa-frame-in-100-lines/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zizzamia%2Fa-frame-in-100-lines/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Zizzamia","download_url":"https://codeload.github.com/Zizzamia/a-frame-in-100-lines/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253551540,"owners_count":21926313,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T18:00:25.167Z","updated_at":"2025-05-11T10:31:00.108Z","avatar_url":"https://github.com/Zizzamia.png","language":"TypeScript","funding_links":[],"categories":["Useful Tools \u0026 Libraries","TypeScript","Uncategorized"],"sub_categories":["Boilerplate repos","Uncategorized"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/Zizzamia/a-frame-in-100-lines/blob/main/public/park-4.png\"\u003e\n    \u003cimg alt=\"OnchainKit logo vibes\" src=\"https://github.com/Zizzamia/a-frame-in-100-lines/blob/main/public/park-4.png\" width=\"auto\"\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n# A Frame in 100 lines (or less)\n\nFarcaster Frames in less than 100 lines, and ready to be deployed to Vercel.\n\nTo test a **deployed** Frame, use: https://warpcast.com/~/developers/frames.\n\nTo test a **localhost** Frame, use: [Framegear](https://onchainkit.xyz/frame/framegear).\nA simple tool that allows you to run and test your frames locally:\n\n- without publishing\n- without casting\n- without spending warps\n\nAnd let us know what you build by either mentioning @zizzamia on [Warpcast](https://warpcast.com/zizzamia) or [X](https://twitter.com/Zizzamia).\n\n\u003cbr /\u003e\n\nHave fun! ⛵️\n\n\u003cbr /\u003e\n\n## App Routing files\n\n- app/\n  - [config.ts](https://github.com/Zizzamia/a-frame-in-100-lines?tab=readme-ov-file#appconfigts)\n  - [layout.tsx](https://github.com/Zizzamia/a-frame-in-100-lines?tab=readme-ov-file#applayouttsx)\n  - [page.tsx](https://github.com/Zizzamia/a-frame-in-100-lines?tab=readme-ov-file#apppagetsx)\n- api/\n  - frame/\n    - [route.ts](https://github.com/Zizzamia/a-frame-in-100-lines?tab=readme-ov-file#appapiframeroutets)\n\n\u003cbr /\u003e\n\n### `app/page.tsx`\n\n```tsx\nimport { getFrameMetadata } from '@coinbase/onchainkit/frame';\nimport type { Metadata } from 'next';\nimport { NEXT_PUBLIC_URL } from './config';\n\nconst frameMetadata = getFrameMetadata({\n  buttons: [\n    {\n      label: 'Story time!',\n    },\n    {\n      action: 'link',\n      label: 'Link to Google',\n      target: 'https://www.google.com',\n    },\n    {\n      label: 'Redirect to pictures',\n      action: 'post_redirect',\n    },\n  ],\n  image: {\n    src: `${NEXT_PUBLIC_URL}/park-3.png`,\n    aspectRatio: '1:1',\n  },\n  input: {\n    text: 'Tell me a boat story',\n  },\n  postUrl: `${NEXT_PUBLIC_URL}/api/frame`,\n});\n\nexport const metadata: Metadata = {\n  title: 'zizzamia.xyz',\n  description: 'LFG',\n  openGraph: {\n    title: 'zizzamia.xyz',\n    description: 'LFG',\n    images: [`${NEXT_PUBLIC_URL}/park-1.png`],\n  },\n  other: {\n    ...frameMetadata,\n  },\n};\n\nexport default function Page() {\n  return (\n    \u003c\u003e\n      \u003ch1\u003ezizzamia.xyz\u003c/h1\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n### `app/layout.tsx`\n\n```tsx\nexport const viewport = {\n  width: 'device-width',\n  initialScale: 1.0,\n};\n\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\n  return (\n    \u003chtml lang=\"en\"\u003e\n      \u003cbody\u003e{children}\u003c/body\u003e\n    \u003c/html\u003e\n  );\n}\n```\n\n### `app/config.ts`\n\n```ts\nexport const NEXT_PUBLIC_URL = 'https://zizzamia.xyz';\n```\n\n### `app/api/frame/route.ts`\n\n```ts\nimport { FrameRequest, getFrameMessage, getFrameHtmlResponse } from '@coinbase/onchainkit/frame';\nimport { NextRequest, NextResponse } from 'next/server';\nimport { NEXT_PUBLIC_URL } from '../../config';\n\nasync function getResponse(req: NextRequest): Promise\u003cNextResponse\u003e {\n  let accountAddress: string | undefined = '';\n  let text: string | undefined = '';\n\n  const body: FrameRequest = await req.json();\n  const { isValid, message } = await getFrameMessage(body, { neynarApiKey: 'NEYNAR_ONCHAIN_KIT' });\n\n  if (isValid) {\n    accountAddress = message.interactor.verified_accounts[0];\n  }\n\n  if (message?.input) {\n    text = message.input;\n  }\n\n  if (message?.button === 3) {\n    return NextResponse.redirect(\n      'https://www.google.com/search?q=cute+dog+pictures\u0026tbm=isch\u0026source=lnms',\n      { status: 302 },\n    );\n  }\n\n  return new NextResponse(\n    getFrameHtmlResponse({\n      buttons: [\n        {\n          label: `🌲 ${text} 🌲`,\n        },\n      ],\n      image: {\n        src: `${NEXT_PUBLIC_URL}/park-1.png`,\n      },\n      postUrl: `${NEXT_PUBLIC_URL}/api/frame`,\n    }),\n  );\n}\n\nexport async function POST(req: NextRequest): Promise\u003cResponse\u003e {\n  return getResponse(req);\n}\n\nexport const dynamic = 'force-dynamic';\n```\n\n\u003cbr /\u003e\n\n## Resources\n\n- [Official Farcaster Frames documentation](https://docs.farcaster.xyz/learn/what-is-farcaster/frames)\n- [Official Farcaster Frame specification](https://docs.farcaster.xyz/reference/frames/spec)\n- [OnchainKit documentation](https://onchainkit.xyz)\n\n\u003cbr /\u003e\n\n## Community ☁️ 🌁 ☁️\n\nCheck out the following places for more OnchainKit-related content:\n\n- Follow @zizzamia ([X](https://twitter.com/zizzamia), [Farcaster](https://warpcast.com/zizzamia)) for project updates\n- Join the discussions on our [OnchainKit warpcast channel](https://warpcast.com/~/channel/onchainkit)\n\n## Authors\n\n- [@zizzamia](https://github.com/zizzamia.png) ([X](https://twitter.com/Zizzamia))\n- [@cnasc](https://github.com/cnasc.png) ([warpcast](https://warpcast.com/cnasc))\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FZizzamia%2Fa-frame-in-100-lines","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FZizzamia%2Fa-frame-in-100-lines","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FZizzamia%2Fa-frame-in-100-lines/lists"}