Static Frontend, Container Backend
A simple frontend app with a containerized backend
A common pattern is to serve a static frontend application (e.g., React, Vue, Svelte) using Static Assets, then pass backend requests to a containerized backend application.
In this example, we'll show an example using a simple index.html
file served as a static asset,
but you can select from one of many frontend frameworks. See our Workers framework examples for more information.
For a full example, see the Static Frontend + Container Backend Template ↗.
{ "name": "cron-container", "main": "src/index.ts", "assets": { "directory": "./dist", "binding": "ASSETS" }, "containers": [ { "class_name": "Backend", "image": "./Dockerfile", "max_instances": 3 } ], "durable_objects": { "bindings": [ { "class_name": "Backend", "name": "BACKEND" } ] }, "migrations": [ { "new_sqlite_classes": [ "Backend" ], "tag": "v1" } ]}
name = "cron-container"main = "src/index.ts"
[assets]directory = "./dist"binding = "ASSETS"
[[containers]]class_name = "Backend"image = "./Dockerfile"max_instances = 3
[[durable_objects.bindings]]class_name = "Backend"name = "BACKEND"
[[migrations]]new_sqlite_classes = [ "Backend" ]tag = "v1"
Create a simple index.html
file in the ./dist
directory.
index.html
<!DOCTYPE html><html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Widgets</title> <script defer src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/3.13.3/cdn.min.js"></script></head>
<body> <div x-data="widgets()" x-init="fetchWidgets()"> <h1>Widgets</h1> <div x-show="loading">Loading...</div> <div x-show="error" x-text="error" style="color: red;"></div> <ul x-show="!loading && !error"> <template x-for="widget in widgets" :key="widget.id"> <li> <span x-text="widget.name"></span> - (ID: <span x-text="widget.id"></span>) </li> </template> </ul>
<div x-show="!loading && !error && widgets.length === 0"> No widgets found. </div>
</div>
<script> function widgets() { return { widgets: [], loading: false, error: null,
async fetchWidgets() { this.loading = true; this.error = null;
try { const response = await fetch('/api/widgets'); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } this.widgets = await response.json(); } catch (err) { this.error = err.message; } finally { this.loading = false; } } } } </script>
</body>
</html>