Node.js
Quick Start
You can scaffold a Frog project with Node.js integrated via the create-frog
CLI:
npm
npm init frog -- -t node
Manual Installation
Build your Frame
Next, scaffold your frame:
src/index.tsx
import { Button, Frog } from 'frog'
export const app = new Frog()
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 Node Server
After that, we will append a Node server to the file.
src/index.tsx
import { serve } from '@hono/node-server'
import { Button, Frog } from 'frog'
export const app = new Frog()
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>
]
})
})
serve({
fetch: app.fetch,
port: 3000,
})
console.log(`Server is running on port ${port}`)
Setup Devtools
Add Frog Devtools after all frames are defined. This way the devtools can automatically discover all your frames.
src/index.tsx
import { serve } from '@hono/node-server'
import { serveStatic } from '@hono/node-server/serve-static'
import { Button, Frog } from 'frog'
import { devtools } from 'frog/dev'
export const app = new Frog()
app.frame('/', (c) => {
...
})
devtools(app, { serveStatic })
^ Devtools should be called after all frames are defined. serve({
fetch: app.fetch,
port: 3000,
})
console.log(`Server is running on port ${port}`)
Add Scripts to package.json
Then we will add a serve
script to serve our Node server.
{
"scripts": {
"dev": "frog dev",
"serve": "tsx src/index.tsx"
},
"dependencies": {
"hono": "latest",
"frog": "latest"
},
"devDependencies": {
"tsx": "latest"
}
}
Navigate to Frame
Then, we can navigate to our frame in the browser:
npm run dev
http://localhost:5173/api
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 /frame/foo
path of the website via their web browser,
they will be redirected to the /foo
path.
Read more on Browser Redirects
src/index.tsx
import { serve } from '@hono/node-server'
import { Button, Frog } from 'frog'
export const app = new Frog({
browserLocation: '/:path',
})
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>
]
})
})
serve({
fetch: app.fetch,
port: 3000,
})
console.log(`Server is running on port ${port}`)