Cloudflare Workers
Cloudflare Workers enable you to deploy serverless code instantly across the globe to give it exceptional performance, reliability, and scale.
Quick Start
You can scaffold a Frog project with Cloudflare Workers integrated via the create-frog CLI:
npm init frog -- -t cloudflare-workerManual Installation
Install Wrangler
npm install wrangler --save-devBuild your Frame
Next, scaffold your frame:
import { Button, Frog } from 'frog'
 
export const app = new Frog({
  title: 'Frog Frame',
})
 
app.frame('/', (c) => {
  const { buttonValue, status } = c
  return c.res({
    image: (
      <div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
        {status === 'initial' ? (
          'Select your fruit!'
        ) : (
          `Selected: ${buttonValue}`
        )}
      </div>
    ),
    intents: [
      <Button value="apple">Apple</Button>,
      <Button value="banana">Banana</Button>,
      <Button value="mango">Mango</Button>
    ]
  })
})Export Default
After that, we export our app via the default export.
import { Button, Frog } from 'frog'
 
export const app = new Frog({
  title: 'Frog Frame',
})
 
app.frame('/', (c) => {
  const { buttonValue, status } = c
  return c.res({
    image: (
      <div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
        {status === 'initial' ? (
          'Select your fruit!'
        ) : (
          `Selected: ${buttonValue}`
        )}
      </div>
    ),
    intents: [
      <Button value="apple">Apple</Button>,
      <Button value="banana">Banana</Button>,
      <Button value="mango">Mango</Button>
    ]
  })
})
 
export default appSetup Devtools
Add Frog Devtools after all frames are defined. This way the devtools can automatically discover all your frames.
import { Button, Frog } from 'frog'
import { devtools } from 'frog/dev'
import { serveStatic } from 'frog/serve-static'
 
export const app = new Frog({
  title: 'Frog Frame',
})
 
app.frame('/', (c) => {
  ...
})
 
Devtools should be called after all frames are defined.const isCloudflareWorker = typeof caches !== 'undefined'if (isCloudflareWorker) {
  devtools(app, {
    serveStatic,
    serveStaticOptions: {
      assetsPath: '/frog',
      manifest: await import('__STATIC_CONTENT_MANIFEST'),
      root: './',
    },
  })
} else {
  devtools(app, { serveStatic })
}
 
export default appAdd Scripts to package.json
Then we will add a Wrangler scripts to our package.json:
{
  "scripts": {
    "dev": "frog dev",
    "wrangler:dev": "wrangler dev src/index.tsx",
    "wrangler:deploy": "wrangler deploy --minify src/index.tsx",
    "wrangler:static": "cp -r ./node_modules/frog/_lib/ui/.frog ./public/frog"
  },
  "dependencies": {
    "hono": "latest",
    "frog": "latest"
  },
  "devDependencies": {
    "@types/bun": "latest",
    "wrangler": "latest",
  }
}Navigate to Frame
Then, we can navigate to our frame in the browser:
npm run dev
http://localhost:5173
Bonus: Deploy
When ready, we can deploy our application.
This example deploys to Cloudflare via the Wrangler CLI (wrangler).
npm run wrangler:deployBonus: Browser Redirects
If a user navigates to your frame in the browser, we may want to redirect them to another webpage that corresponds to the frame.
In the example below, when a user navigates to the /frame/foo path of the website via their web browser,
they will be redirected to the /foo path.
Read more on Browser Redirects
import { Button, Frog } from 'frog'
 
export const app = new Frog({
  browserLocation: '/:path',
  title: 'Frog Frame',
})
 
app.frame('/frame/:path', (c) => {
  const { buttonValue, status } = c
  return c.res({
    image: (
      <div style={{ color: 'white', display: 'flex', fontSize: 60 }}>
        {status === 'initial' ? (
          'Select your fruit!'
        ) : (
          `Selected: ${buttonValue}`
        )}
      </div>
    ),
    intents: [
      <Button value="apple">Apple</Button>,
      <Button value="banana">Banana</Button>,
      <Button value="mango">Mango</Button>
    ]
  })
})
 
export default app