Example of a Cloudflare Pages server side rendering (SSR) project powered by Hono.

Overview

Hono SSR on Cloudflare Pages

Example of a Cloudflare Pages server side rendered (SSR) project powered by Hono.

This project demonstrates:

  • Accessing environment variables
  • Using Cloudflare KV to dynamically add and delete posts
  • Using Cloudflare KV to display a dynamic "visitor counter"
  • Custom Hono middleware to count all visits
  • A minimal TypeScript configuration
  • Deploying fixed assets (non-generated) like images, CSS, etc.

Demo

This project can be viewed at https://hono-pages-ssr.codedemos.dev.

General Guidance and Explanation of Code

Paths

The example is configured to use @ as an alias to the src directory. Throughout the code base, files can be imported using the @ alias.

Examples

  • import { Layout } from "@/components/Layout";
  • import type { Post } from "@/index";

Environment Variables

Rather than use a .env file, this project uses a .dev.vars file. All "secrets" or other environment variables should be added to this file. During development, Wrangler automatically makes these variables available to the project in c.env.

For real projects, this file should NOT be added to your Git repository. It should be added to the .gitignore file.

To use these variables in preview or production, they need to be added via the Cloudflare dashboard.

In addition, the NODE_VERSION variable should be added with a value of 16 or 17.

Be sure to add the appropriate variables to both the "Preview" and "Production" sections.

If running this project in preview or production results in "Internal Server Error", it is highly likely the variables were not added in "Preview" / "Production" or the KV namespaces and bindings were not added.

KV Namespaces and Bindings

In development, the KV Namespaces are included in the dev:wrangler script in package.json.

For production or preview, use the Cloudflare dashboard to create two namespaces:

  • HONO_PAGES_BLOG_POSTS
  • HONO_PAGES_COUNTER

NOTE: The namespaces can be called anything per personal/organizational preferences.

Next, these two new namespaces must be bound to the Pages project. Unless changed throughout the code base, the bindings must be named as follows.

  • HONO_PAGES_BLOG_POSTS
  • HONO_PAGES_COUNTER

Output

All dev and build processes output to the public directory. When the process is built by Cloudflare Pages, the _worker.js file is used to run the project from the edge.

Additional Assets

Any assets such as favicon, CSS, images, etc. should be located in the public directory. If desired, additional folder nesting can be used for better organization.

To reference these assets, use the root path (/) along with any other nested paths.

Examples

  • <link rel="stylesheet" href="/index.css" />
  • <link rel="shortcut icon" href="/assets/favicon.ico" />

Development

  • Install packages
    • Yarn : yarn
    • npm : npm install
  • Run in development mode
    • Yarn : yarn dev
    • npm : npm run dev
  • Format all code per prettier configuration
    • Yarn : yarn format
    • npm : npm run format

New Development and Production Steps

If additional development or build steps, such as adding TailwindCSS, are needed, add them to the scripts section of package.json.

  • "dev:css": "tailwindcss -o ./public/assets/tailwind.css --watch",
  • "build:css": "tailwindcss -o ./public/assets/tailwind.css",

Deploying to Production

Git Based Workflow

If this project is added to the Cloudflare Dashboard via a Git provider, any changes to the primary branch will result in deployment to production.

Changes to feature branches will result in deployment to a unique preview instance.

When creating the project for the first time in the Cloudflare dashboard, be sure to add all environment variables and KV namespace bindings before completing the project. Otherwise, the first build will fail.

Manual Deployment

To deploy the project manually, run the deploy script to push the project to Cloudflare.

  • Yarn : yarn deploy
  • npm : npm run deploy

If the project does not exist already, the first deployed version will not run properly. It will be missing environment variables and KV Namespace bindings.

These can be added to the project before the next deployment.

Credits

This example project is based on the Hono "blog" example by Yusuke Wada.

This example has been modified to support running on Cloudflare Pages based on guidance from Rishav Sharan in this pull request.

Many thanks 🙏 to Yusuke Wada for the amazing Hono library!

Author

Justin Noel https://github.com/justinnoel

License

Distributed under the MIT License.

You might also like...

Use Cloudflare Pages Functions as a reverse proxy with custom domain support.

Use Cloudflare Pages Functions as a reverse proxy with custom domain support.

cf-page-func-proxy Use Cloudflare Pages Functions as a reverse proxy with custom domain support. Getting Start 1.下载或是Fork本仓库 2.修改_worker.js中的url.hostn

Dec 23, 2022

A Cloudflare Workers service that fetches and renders Notion pages as HTML, Markdown, or JSON.

notion-fetch A Cloudflare Workers service that fetches and renders Notion pages as HTML, Markdown, or JSON. Powered by Durable Objects and R2. Usage P

Jan 6, 2023

A CloudFlare Worker / script / bot to sync Notion pages publicly as GitHub Discussions.

A CloudFlare Worker / script / bot to sync Notion pages publicly as GitHub Discussions.

notion-github-sync This bot syncs public Notion pages as GitHub Discussions/Issues. It's done periodically, based on the pages shared with the Notion

Dec 22, 2022

Running Next.js on Cloudflare Pages.

Nextflare - Run Next.js Edge Runtime on Cloudflare Pages (Workers) NOTE: We're still actively updating this repository, docs, and preparing a potentia

Jan 3, 2023

Remix run stack built for the edge (cloudflare pages and d1)

Remix run stack built for the edge (cloudflare pages and d1)

Remix Race Stack Learn more about Remix Stacks. npx create-remix@latest --template jose-donato/race-stack What's in the stack Cloudflare Pages for ho

Aug 10, 2023

This is an VanillaJS SPA example with function based rendering.

This is an VanillaJS SPA example with function based rendering.

Function-Based-Rendering This is an VanillaJS SPA example with function based rendering. Here's how to create Views by function composition and how to

Oct 16, 2021

A starter project that includes theme switching functionality with Stitches CSS-in-JS and Remix SSR.

Welcome to Remix! Remix Docs Development From your terminal: npm run dev This starts your app in development mode, rebuilding assets on file changes.

Dec 22, 2022

Type-safe session for all Astro SSR project

Astro Session Why use Astro Session? When building server application with Astro, you will often need session system to identify request coming from t

Dec 19, 2022

Make drag-and-drop easier using DropPoint. Drag content without having to open side-by-side windows

Make drag-and-drop easier using DropPoint. Drag content without having to open side-by-side windows

Make drag-and-drop easier using DropPoint! DropPoint helps you drag content without having to open side-by-side windows Works on Windows, Linux and Ma

Dec 29, 2022
Owner
Justin Noel
(Mobile) app developer focused on the front-end but full stack capable: React Native • Ionic Framework • React
Justin Noel
Minimum project with Hono.

Hono minimum project This is a minimum project with Hono[炎]. Features Minimum TypeScript Esbuild to build miniflare 2.x to develop Wrangler 2.0 Beta t

Yusuke Wada 60 Dec 25, 2022
Hono on Node.js

HTTP server for Hono on Node.js This project is still experimental. Hono is ultrafast web framework for Cloudflare Workers, Deno, and Bun. It's not fo

Hono 33 Jan 3, 2023
A JSDOM alternative with support for server side rendering of web components

About A JSDOM alternative with support for server side rendering of web components. Happy DOM aim to support the most common functionality of a web br

David Ortner 1.6k Dec 30, 2022
A server side rendering framework for Deno CLI and Deploy. 🦟 🦕

nat A server side rendering framework for Deno CLI and Deploy. Incorporating acorn, nano-jsx, and twind, it provides the tooling to provide a server c

oak 12 Nov 17, 2022
Fast and minimal JS server-side writer and client-side manager.

unihead Fast and minimal JS <head> server-side writer and client-side manager. Nearly every SSR framework out there relies on server-side components t

Jonas Galvez 24 Sep 4, 2022
Easy server-side and client-side validation for FormData, URLSearchParams and JSON data in your Fresh app 🍋

Fresh Validation ??     Easily validate FormData, URLSearchParams and JSON data in your Fresh app server-side or client-side! Validation Fresh Validat

Steven Yung 20 Dec 23, 2022
Provide single node.js server with popular ssr and web framework

create-fullstack-node-app Provide single node.js server with popular ssr and web framework With NPM: npx create-fullstack-node-app@latest Frameworks:

keyboard3 2 Sep 26, 2022
A set of useful helper methods for writing functions to handle Cloudflare Pub/Sub messages (https://developers.cloudflare.com/pub-sub/)

pubsub A set of useful helper methods for writing functions to handle Cloudflare Pub/Sub messages. This includes: A isValidBrokerRequest helper for au

Cloudflare 18 Dec 4, 2022
Connect to a Postgres database from a Cloudflare Worker, using Cloudflare Tunnel

Cloudflare Workers Postgres Client This is an experimental module. Heavily based on cloudflare/worker-template-postgres, but cleaned up and bundled in

BubblyDoo 17 Dec 22, 2022
Functional-style Cloudflare Durable Objects with direct API calls from Cloudflare Workers and TypeScript support.

durable-apis Simplifies usage of Cloudflare Durable Objects, allowing a functional programming style or class style, lightweight object definitions, a

Dabble 12 Jan 2, 2023