Cloudflare Pages
Cloudflare Pages is an edge platform for full-stack web applications. It serves static files and dynamic content provided by Cloudflare Workers.
Hono fully supports Cloudflare Pages. It introduces a delightful developer experience. Vite's dev server is fast, and deploying with Wrangler is super quick.
1. Setup
A starter for Cloudflare Pages is available. Start your project with "create-hono" command.
npm create hono@latest my-appnpm create hono@latest my-appyarn create hono my-appyarn create hono my-apppnpm create hono my-apppnpm create hono my-appbunx create-hono my-appbunx create-hono my-appdeno run -A npm:create-hono my-appdeno run -A npm:create-hono my-appMove into my-app and install the dependencies.
cd my-app
npm icd my-app
npm icd my-app
yarncd my-app
yarncd my-app
pnpm icd my-app
pnpm icd my-app
bun icd my-app
bun iBelow is a basic directory structure.
./
├── package.json
├── public
│ └── static // Put your static files.
│ └── style.css // You can refer to it as `/static/style.css`.
├── src
│ ├── index.tsx // The entry point for server-side.
│ └── renderer.tsx
├── tsconfig.json
└── vite.config.ts./
├── package.json
├── public
│ └── static // Put your static files.
│ └── style.css // You can refer to it as `/static/style.css`.
├── src
│ ├── index.tsx // The entry point for server-side.
│ └── renderer.tsx
├── tsconfig.json
└── vite.config.ts2. Hello World
Edit src/index.tsx like the following:
import { Hono } from 'hono'
import { renderer } from './renderer'
const app = new Hono()
app.get('*', renderer)
app.get('/', (c) => {
return c.render(<h1>Hello, Cloudflare Pages!</h1>)
})
export default appimport { Hono } from 'hono'
import { renderer } from './renderer'
const app = new Hono()
app.get('*', renderer)
app.get('/', (c) => {
return c.render(<h1>Hello, Cloudflare Pages!</h1>)
})
export default app3. Run
Run the development server locally. Then, access http://localhost:5173 in your Web browser.
npm run devnpm run devyarn devyarn devpnpm devpnpm devbun run devbun run dev4. Deploy
If you have a Cloudflare account, you can deploy to Cloudflare. In package.json, $npm_execpath needs to be changed to your package manager of choice.
npm run deploynpm run deployyarn deployyarn deploypnpm deploypnpm deploybun run deploybun run deployBindings
You can use Cloudflare Bindings like variables, KV, D1, and others. Edit the vite.config.ts like the following:
import { getEnv } from '@hono/vite-dev-server/cloudflare-pages'
export default defineConfig({
plugins: [
pages(),
devServer({
entry: 'src/index.tsx',
env: getEnv({
bindings: {
NAME: 'Hono',
},
kvNamespaces: ['MY_KV'],
}),
}),
],
})import { getEnv } from '@hono/vite-dev-server/cloudflare-pages'
export default defineConfig({
plugins: [
pages(),
devServer({
entry: 'src/index.tsx',
env: getEnv({
bindings: {
NAME: 'Hono',
},
kvNamespaces: ['MY_KV'],
}),
}),
],
})When using D1, your app will read .mf/d1/DB/db.sqlite which is generated automatically with the following configuration:
export default defineConfig({
plugins: [
pages(),
devServer({
entry: 'src/index.tsx',
env: getEnv({
d1Databases: ['DB'],
d1Persist: true,
}),
}),
],
})export default defineConfig({
plugins: [
pages(),
devServer({
entry: 'src/index.tsx',
env: getEnv({
d1Databases: ['DB'],
d1Persist: true,
}),
}),
],
})Client-side
You can write client-side scripts and import them into your application using Vite's features. If /src/client.ts is the entry point for the client, simply write it in the script tag. Additionally, i is useful for detecting whether it's running on a dev server or in the build phase.
app.get('/', (c) => {
return c.html(
<html>
<head>
{import.meta.env.PROD ? (
<>
<script type='module' src='/static/client.js'></script>
</>
) : (
<>
<script type='module' src='/src/client.ts'></script>
</>
)}
</head>
<body>
<h1>Hello</h1>
</body>
</html>
)
})app.get('/', (c) => {
return c.html(
<html>
<head>
{import.meta.env.PROD ? (
<>
<script type='module' src='/static/client.js'></script>
</>
) : (
<>
<script type='module' src='/src/client.ts'></script>
</>
)}
</head>
<body>
<h1>Hello</h1>
</body>
</html>
)
})In order to build the script properly, you can use the example config file vite.config.ts as shown below.
import pages from '@hono/vite-cloudflare-pages'
import devServer from '@hono/vite-dev-server'
import { defineConfig } from 'vite'
export default defineConfig(({ mode }) => {
if (mode === 'client') {
return {
build: {
rollupOptions: {
input: './src/client.ts',
output: {
entryFileNames: 'static/client.js',
},
},
emptyOutDir: false,
},
}
} else {
return {
plugins: [
pages(),
devServer({
entry: 'src/index.tsx',
}),
],
}
}
})import pages from '@hono/vite-cloudflare-pages'
import devServer from '@hono/vite-dev-server'
import { defineConfig } from 'vite'
export default defineConfig(({ mode }) => {
if (mode === 'client') {
return {
build: {
rollupOptions: {
input: './src/client.ts',
output: {
entryFileNames: 'static/client.js',
},
},
emptyOutDir: false,
},
}
} else {
return {
plugins: [
pages(),
devServer({
entry: 'src/index.tsx',
}),
],
}
}
})You can run the following command to build the server and client script.
vite build && vite build --mode clientvite build && vite build --mode client
Hono