Vercel Serverless
Quick Start
You can scaffold a Frog project with Vercel Serverless integrated via the create-frog
CLI:
npm init frog -- -t vercel
Manual Installation
Install Vercel
npm install vercel --save-dev
Build your Frame
Next, scaffold your frame:
import { Button, Frog } from 'frog'
// Uncomment to use Edge Runtime.
// export const config = {
// runtime: 'edge',
// }
export const app = new Frog({
basePath: '/api',
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>
]
})
})
Add Vercel Handlers
After that, we will append Vercel handlers to the file.
import { Button, Frog } from 'frog'
import { handle } from 'frog/next'
// Uncomment to use Edge Runtime.
// export const config = {
// runtime: 'edge',
// }
export const app = new Frog({
basePath: '/api',
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 const GET = handle(app)
export const POST = handle(app)
Setup 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 { handle } from 'frog/next'
import { devtools } from 'frog/dev'
import { serveStatic } from 'frog/serve-static'
export const app = new Frog({
basePath: '/api',
title: 'Frog Frame',
})
app.frame('/', (c) => {
...
})
Devtools should be called after all frames are defined.if (import.meta.env?.MODE === 'development') devtools(app, { serveStatic })else devtools(app, { assetsPath: '/.frog' })
export const GET = handle(app)
export const POST = handle(app)
Add Scripts to package.json
Then we will add a build
& deploy
script to deploy our Vercel Serverless function.
{
"scripts": {
"build": "frog vercel-build",
"dev": "frog dev",
"deploy": "vercel"
},
"dependencies": {
"hono": "latest",
"frog": "latest"
},
"devDependencies": {
"vercel": "latest"
}
}
Navigate to Frame
Then, we can navigate to our frame in the browser:
npm run dev
http://localhost:5173/api
Bonus: Deploy
When ready, we can deploy our application.
This example deploys to Vercel via the Vercel CLI (vercel
).
npm run deploy
Bonus: 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 /api/
path of the website via their web browser,
they will be redirected to the /
path.
Read more on Browser Redirects
import { Button, Frog } from 'frog'
import { handle } from 'frog/next'
// Uncomment to use Edge Runtime.
// export const config = {
// runtime: 'edge',
// }
export const app = new Frog({
basePath: '/api',
browserLocation: '/:path'
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 const GET = handle(app)
export const POST = handle(app)