a422015028/cloudflareassistant/pages-deploy-guide
Claude Code and agent skill by a422015028/cloudflareassistant
- community
Checking that the SKILL.md file is still in the repository.
Guides Cloudflare Pages project creation and deployment via the CloudFlareAssistant Android app. Invoke when user asks how to write/structure a Pages project for deployment, or needs to know supported/unsupported features.
Install
npx vskill@latest install a422015028/cloudflareassistant/pages-deploy-guideSKILL.md
Pages Deploy Guide (CloudFlareAssistant)
Guide for writing Cloudflare Pages projects that deploy correctly through the CloudFlareAssistant Android app.
Deployment Modes
The app supports 5 deployment modes, selected automatically by file type and structure:
| Mode | Trigger | Description | |
|---|---|---|---|
Single .html file | Upload *.html or *.htm | Deploys as /index.html static asset | |
Single .js file | Upload *.js | Deploys as _worker.js (Module Worker syntax) | |
_worker.js single file | Zip contains /_worker.js at root | Advanced mode: full request control via export default { fetch } | |
functions/ standard mode | Zip contains /functions/ directory | File-based routing with TypeScript/JSX support | |
| Pure static | Zip with only static assets | HTML/CSS/JS/images served directly |
Priority order: _worker.js > functions/ > pure static.
Not supported: _worker.js/ directory mode (Cloudflare direct upload API does not support it).
Project Structure
Pure Static
_worker.js Advanced Mode
functions/ Standard Mode
Nested Directory Traversal
If the zip contains a single top-level wrapper directory (e.g., myproject/), the app automatically traverses into it. Exceptions: _worker.js and functions directories are never traversed into. public/ directories ARE traversed.
Functions Standard Mode — Supported Features
| Feature | Supported | Notes | |
|---|---|---|---|
| File-based routing | Yes | hello.js → /hello | |
Dynamic routes [param] | Yes | Single path segment matching | |
Catch-all [[param]] | Yes | Multi-path segment matching, returns array | |
Middleware _middleware.js | Yes | context.next() chaining, sorted by mount path depth | |
| Method-specific exports | Yes | onRequestGet, onRequestPost, onRequestPut, onRequestPatch, onRequestDelete, onRequestOptions, onRequestHead | |
onRequest (all methods) | Yes | Fallback when no method-specific export | |
TypeScript .ts | Yes | Sucrase type stripping (offline, no bundler) | |
TSX .tsx | Yes | Sucrase + JSX transform | |
JSX .jsx | Yes | Sucrase + JSX transform | |
| Module imports | Yes | Relative paths auto-rewritten to ./func_N.js | |
| NPM packages | Yes | esbuild-wasm bundles bare imports via esm.sh CDN (on-demand download) | |
| Static asset fallback | Yes | env.ASSETS.fetch(request) | |
_routes.json | Yes | Auto-generated or user-provided |
JSX Pragma
JSX transforms default to React.createElement. Since Workers runtime has no React, use a custom pragma:
The app detects /** @jsx functionName */ comments and configures both Sucrase and esbuild accordingly.
Critical: esbuild scans ALL comments in the source file for @jsx directives. Source-file @jsx pragma takes precedence over the jsxFactory build option. Never put @jsx in any comment other than the actual pragma directive — a comment like // 验证 @jsx pragma 生效 will be interpreted as a pragma, overriding the intended factory function and causing ReferenceError at runtime.
Module Import Resolution
The app rewrites relative imports (./, ../) to ./func_N.js format. Resolution tries:
- 7 extensions:
"",.js,.ts,.tsx,.jsx,.mjs,.cjs - 4 index variants:
/index.js,/index.ts,/index.tsx,/index.jsx - Fuzzy suffix matching as fallback
- Unresolved paths fall back to
./func_0.js
All three import forms are handled: from "...", import "...", import("...").
NPM Package Support (esbuild-wasm)
Files containing bare imports (e.g., import React from 'react') are automatically routed to esbuild-wasm for bundling. The app detects bare imports — any import specifier that is NOT a relative path (./, ../), absolute path (/), or URL (http://, https://).
How it works:
- App detects bare imports in function files (any extension:
.js,.ts,.tsx,.jsx) - esbuild-wasm files are downloaded on-demand (not bundled in APK) from jsdelivr CDN
- esbuild bundles each file: inlines NPM dependencies from esm.sh CDN, transforms TS/JSX
- Relative imports (
./,../) are marked asexternal— preserved for the import rewriter - Output is self-contained JS with NPM code inlined + relative imports preserved
Example:
Requirements:
- Network connection required (esbuild-wasm download + esm.sh CDN fetch)
- First use triggers ~12MB download (esbuild-wasm.js + esbuild.wasm), cached afterward
- Files without bare imports still use Sucrase (offline, 193KB, no download needed)
Dual-path architecture:
- Files WITH bare imports → esbuild-wasm (NPM bundling + TS/JSX transform)
- Files WITHOUT bare imports → Sucrase (TS/JSX transform only, offline)
Version management:
- App queries npm registry (
registry.npmjs.org/esbuild-wasm/latest) for latest version - Local cached version compared against latest; re-downloads if outdated
- Version cached in app private storage (
esbuild/version.txt)
Multi-CDN download:
- jsdelivr (
cdn.jsdelivr.net) as primary CDN, unpkg (unpkg.com) as fallback - Downloads
esm/browser.min.js(JS) andesbuild.wasm(WASM binary) separately - Files stored in app private storage (
filesDir/esbuild/), never in public directories
esm.sh CDN integration:
- Bare imports resolved via
https://esm.sh/{package}?bundle ?bundleparameter returns self-contained single file — inlines all submodule dependencies (e.g., crypto-js's internal./coreimports)- CDN module relative imports resolved against final redirected URL
- Relative imports from original source file marked as
external(not sent to CDN)
WebView integration:
- esbuild-wasm runs inside Android WebView with
worker: falsefor compatibility shouldInterceptRequestintercepts local WASM/JS files from private storage- CDN fetches (esm.sh) pass through unintercepted
- Dynamic
import()loads esbuild ESM module (avoids<script type="module">scope issues)
JSX pragma detection:
- App detects
/** @jsx h */comments and sets esbuild'sjsxFactoryoption - Also detects
/** @jsxFrag Fragment */for fragment pragma - Warning: esbuild also scans ALL source comments for
@jsx— see Common Pitfalls #5
Functions Standard Mode — Unsupported Features
| Feature | Reason | Workaround | |
|---|---|---|---|
| TS path aliases | tsconfig.json not read | Use relative paths (../utils/types) | |
| Dynamic import variables | Static analysis only | Use static import paths | |
| Node.js APIs | Workers runtime (not Node.js) | Use nodejs_compat compatibility flag for limited support | |
| esbuild RE2 regex lookahead | esbuild's onResolve/onLoad filters use Go RE2 engine (no negative lookahead) | Split into sequential callback handlers |
Static Asset Features
.assetsignore
Exclude files from asset upload using glob patterns:
Supported glob patterns:
file.md— match root-level file*.md— match root-level.mdfiles**/*.md— recursively match all.mdfilesdocs/*— match files directly underdocs/docs/**/*.md— recursively match.mdunderdocs/
_headers and _redirects
Uploaded as static assets. Cloudflare automatically parses them. Note: these do NOT apply to Pages Functions responses — handle headers/redirects in Function code directly.
_routes.json
Controls which paths invoke Functions vs static assets. Auto-generated if absent:
User-provided _routes.json takes priority. Place at project root.
Project Configuration
Compatibility Date
Set via UI input field. Default: 2026-06-16. Applied to both production and preview environments.
Compatibility Flags
Set via UI input field (comma or newline separated). Example: nodejs_compat. Applied via PATCH project API.
Common flags:
nodejs_compat— enables Node.js compatibility layerexperimental_global_cjs_imports— CommonJS import support
Bindings (via Project Settings API)
All bindings are configured through the app's project settings, not in deployment files:
- Environment variables (
env_vars) - KV namespaces (
kv_namespaces) - R2 buckets (
r2_buckets) - D1 databases (
d1_databases) - Durable Objects (
durable_objects) - Service bindings (
services)
Asset Config
not_found_page— custom 404 page pathpretty_urls— enable/disable trailing slash normalization
File Type Restrictions
The app accepts uploads of:
.zip— project archive (all modes).js— single Worker script.htm/.html— single static page
API Flow
The app follows the Wrangler direct upload flow:
- Get upload JWT token
- Upload assets as Base64 to asset store
- Upsert asset hashes
- Create deployment with manifest:
- Pure static:
manifestonly _worker.js:manifest+_worker.bundle(nested multipart with metadata + module)functions/:manifest+_worker.bundle+functions-filepath-routing-config.json+_routes.json
Common Pitfalls
- `_worker.js` must use Module syntax:
export default { async fetch(request, env) { ... } }, notaddEventListener('fetch', ...). - Functions must export `onRequest`: or method-specific variants like
onRequestGet. - No `_worker.js/` directory: Use single file or
functions/mode instead. - JSX needs pragma: Add
/** @jsx h */at file top and define/importhfunction. - Never put `@jsx` in comments: esbuild scans ALL comments for
@jsxdirectives. A comment like// 验证 @jsx pragmawill be misinterpreted as a pragma, overriding@jsx hand causingReferenceError. Only use@jsxin the actual pragma directive. - NPM packages need network: Bare imports trigger esbuild-wasm (requires download + CDN access). Relative imports work offline via Sucrase.
- `_headers` and `_redirects` don't apply to Functions: Handle in code.
- Static assets in `functions/` mode: Place outside
functions/directory at project root. - QR code async:
QRCode.toDataURL()returns a Promise — mustawaitit, otherwise output shows[object Promise].
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingpages-deploy-guide/SKILL.md
Popularity
- Repository stars
- 134
- Repository forks
- 29
- 7-day trend score
- 25
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/a422015028/cloudflareassistant/pages-deploy-guide)