├── .gitignore ├── ReadMe.md ├── demo ├── functions │ ├── _middleware.ts │ ├── dashboard │ │ ├── [paramId] │ │ │ ├── _middleware.ts │ │ │ └── index.ts │ │ ├── _middleware.ts │ │ └── index.ts │ ├── index.ts │ ├── logging-in.ts │ ├── logout.ts │ └── verify.ts ├── package-lock.json ├── package.json ├── pnpm-lock.yaml ├── schema.sql ├── src │ ├── components │ │ ├── NavBar.ts │ │ ├── Spinner.ts │ │ ├── Stat.ts │ │ ├── Table.ts │ │ └── Toast.ts │ ├── layouts │ │ ├── DashLayout.ts │ │ ├── RootLayout.ts │ │ └── SubLayout.ts │ └── lib │ │ └── html.ts ├── static │ └── assets │ │ ├── css │ │ └── output.css │ │ ├── img │ │ ├── avatar-brice.png │ │ ├── avatar-hart.png │ │ ├── avatar-marjy.png │ │ └── avatar-yancy.png │ │ └── js │ │ ├── _hyperscript.min.js │ │ └── htmx.min.js ├── tailwind.config.js ├── tailwind.css ├── tsconfig.json └── wrangler.toml ├── index.ts ├── install.js ├── package-lock.json ├── package.json ├── screenshot.png ├── templates └── basic │ ├── functions │ ├── _middleware.ts │ └── index.ts │ ├── package.json │ ├── src │ └── layouts │ │ └── RootLayout.ts │ ├── static │ ├── css │ │ └── main.css │ └── js │ │ ├── _hyperscript.min.js │ │ └── htmx.min.js │ └── tsconfig.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | 3 | logs 4 | _.log 5 | npm-debug.log_ 6 | yarn-debug.log* 7 | yarn-error.log* 8 | lerna-debug.log* 9 | .pnpm-debug.log* 10 | 11 | # Diagnostic reports (https://nodejs.org/api/report.html) 12 | 13 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 14 | 15 | # Runtime data 16 | 17 | pids 18 | _.pid 19 | _.seed 20 | \*.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | 28 | coverage 29 | \*.lcov 30 | 31 | # nyc test coverage 32 | 33 | .nyc_output 34 | 35 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 36 | 37 | .grunt 38 | 39 | # Bower dependency directory (https://bower.io/) 40 | 41 | bower_components 42 | 43 | # node-waf configuration 44 | 45 | .lock-wscript 46 | 47 | # Compiled binary addons (https://nodejs.org/api/addons.html) 48 | 49 | build/Release 50 | 51 | # Dependency directories 52 | 53 | node_modules/ 54 | demo/node_modules/ 55 | jspm_packages/ 56 | 57 | # Snowpack dependency directory (https://snowpack.dev/) 58 | 59 | web_modules/ 60 | 61 | # TypeScript cache 62 | 63 | \*.tsbuildinfo 64 | 65 | # Optional npm cache directory 66 | 67 | .npm 68 | 69 | # Optional eslint cache 70 | 71 | .eslintcache 72 | 73 | # Optional stylelint cache 74 | 75 | .stylelintcache 76 | 77 | # Microbundle cache 78 | 79 | .rpt2_cache/ 80 | .rts2_cache_cjs/ 81 | .rts2_cache_es/ 82 | .rts2_cache_umd/ 83 | 84 | # Optional REPL history 85 | 86 | .node_repl_history 87 | 88 | # Output of 'npm pack' 89 | 90 | \*.tgz 91 | 92 | # Yarn Integrity file 93 | 94 | .yarn-integrity 95 | 96 | # dotenv environment variable files 97 | 98 | .env 99 | .env.development.local 100 | .env.test.local 101 | .env.production.local 102 | .env.local 103 | 104 | # parcel-bundler cache (https://parceljs.org/) 105 | 106 | .cache 107 | .parcel-cache 108 | 109 | # Next.js build output 110 | 111 | .next 112 | out 113 | 114 | # Nuxt.js build / generate output 115 | 116 | .nuxt 117 | dist 118 | 119 | # Gatsby files 120 | 121 | .cache/ 122 | 123 | # Comment in the public line in if your project uses Gatsby and not Next.js 124 | 125 | # https://nextjs.org/blog/next-9-1#public-directory-support 126 | 127 | # public 128 | 129 | # vuepress build output 130 | 131 | .vuepress/dist 132 | 133 | # vuepress v2.x temp and cache directory 134 | 135 | .temp 136 | .cache 137 | 138 | # Docusaurus cache and generated files 139 | 140 | .docusaurus 141 | 142 | # Serverless directories 143 | 144 | .serverless/ 145 | 146 | # FuseBox cache 147 | 148 | .fusebox/ 149 | 150 | # DynamoDB Local files 151 | 152 | .dynamodb/ 153 | 154 | # TernJS port file 155 | 156 | .tern-port 157 | 158 | # Stores VSCode versions used for testing VSCode extensions 159 | 160 | .vscode-test 161 | 162 | # yarn v2 163 | 164 | .yarn/cache 165 | .yarn/unplugged 166 | .yarn/build-state.yml 167 | .yarn/install-state.gz 168 | .pnp.\* 169 | 170 | # wrangler project 171 | 172 | .dev.vars 173 | .wrangler/ 174 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # Cloudflare Pages + HTMX 2 | 3 | This is a starter project to create a zero-build web-app using [HTMX](https://htmx.org/) on [Cloudflare](https://dash.cloudflare.com/). It uses [\_hyperscript](https://hyperscript.org) for additional (rare) client side JS and [TailwindCSS](https://tailwindcss.com/) and [DaisyUI](https://daisyui.com/) for styling and theme. 4 | 5 | ## Live Demo 6 | 7 |  8 | 9 | [https://cloudflare-htmx.pages.dev/](https://cloudflare-htmx.pages.dev/) 10 | 11 | ## Getting Started 12 | 13 | ```bash 14 | $ git clone https://github.com/stukennedy/cloudflare-htmx.git 15 | $ cd cloudflare-htmx 16 | $ npm i 17 | $ npm run dev 18 | ``` 19 | 20 | - NextJS-style routing files, written in Typescript, are found in the `functions` folder. 21 | - Endpoints should return HTML strings wrapped in a `new Response()`. 22 | - `import { html, view } from "@lib/html"` declaration allows a string template to be syntax highlighted in VS Code 23 | - Use `_middleware.ts` files at any level of the folder structure to apply a layout. You should use this to at least apply your root level HTML wrapper. 24 | e.g. 25 | 26 | ```typescript 27 | // functions/_middleware.ts 28 | import RootLayout from '@layouts/RootLayout'; 29 | import { applyLayout } from '@lib/html'; 30 | 31 | export const onRequestGet = [applyLayout(RootLayout)]; 32 | ``` 33 | 34 | This makes sure that the `RootLayout` which is of type `LayoutFunction` wraps all `GET` requests throughout the app. 35 | Our `RootLayout.ts` looks like this: 36 | 37 | ```typescript 38 | import SupabaseAuth from '@components/SupabaseAuth'; 39 | import { html, LayoutFunction } from '@lib/html'; 40 | 41 | // this is the layout for the entire site 42 | const _layout: LayoutFunction = ({ children }) => { 43 | const title = 'Cloudflare Pages + HTMX + Hyperscript'; 44 | return html` 45 | 46 | 47 |
48 | 49 | 50 |${url}
7 | npm i daisyui
8 | installing...
9 | Done!
10 | 24 | 31 | | 32 |Name | 33 |Job | 34 |Favorite Color | 35 |36 | |
---|---|---|---|---|
45 | 48 | | 49 |
50 |
51 |
66 |
52 |
59 |
53 |
58 |
60 |
65 | ${item.name}
61 |
62 | ${item.country}
63 |
64 | |
67 |
68 | ${item.company}
69 | 70 | ${item.job} 73 | |
74 | ${item.color} | 75 |76 | 77 | | 78 |
83 | | 84 | | 85 | | 86 | | 87 | |
96 | | Name | 97 |Job | 98 |Favorite Color | 99 |100 | |