ai newsSa., 24. Okt.
EilmeldungDeepSeek V4.1-Flash-1017 überzeugt in Benchmarks, Zweifel an Bewertungsmethodik bleiben

When AI-generated HTML needs a backend

AI disclosure: I used AI assistance to draft and edit this article. I reviewed the technical claims against the browser documentation linked below and checked the examples for consistency. The code is intentionally simplified. An AI assistant can produce a polished HTML demo in a minute. The page h

dev.toSamstag 05:20 · 24.10.5 Min. Lesezeit
Bild: dev.to

AI disclosure: I used AI assistance to draft and edit this article. I reviewed the technical claims against the browser documentation linked below and checked the examples for consistency. The code is intentionally simplified.

An AI assistant can produce a polished HTML demo in a minute. The page has buttons, calculations, a form, and maybe a chart. It looks like an application, so it is easy to assume that publishing the HTML also publishes everything behind it.

That last step needs a closer look. A static page can render, calculate, filter, animate, and remember a preference in one browser. It cannot safely hold a private API key, turn every visitor's browser into your shared database, or make a service running only on your laptop available to everyone else.

Here is the checklist I use to decide whether a generated page is ready for static hosting or needs a backend.

This code can make a feedback form look finished:

const items = JSON. parse ( localStorage. getItem ( ' feedback ' ) || ' [] ' ); items. push ({ message, createdAt: new Date (). toISOString () }); localStorage. setItem ( ' feedback ', JSON. stringify ( items )); render ( items ); Enter fullscreen mode Exit fullscreen mode It preserves the current visitor's entries in that browser. It does not send them to the page owner, and another visitor will not see them. Browser storage is useful for a draft, a preference, or a local-only tool. It is not a shared submissions database.

There is another preview trap: the required behavior of localStorage for file: URLs is undefined and can vary between browsers. A result you see after double-clicking an HTML file is not a reliable test of what storage will do after deployment.

If you only need a visual demonstration, keep the data in memory or use a small fixture and label the action clearly: "Demo only — nothing is submitted." If someone must receive the submission, use an HTTPS endpoint and show what happened after the server responds.

Generated code often contains a call like this:

const response = await fetch ( ' http://localhost:3000/api/quote ' ); const quote = await response. json (); Enter fullscreen mode Exit fullscreen mode While you develop, that address can reach a server on your machine. After you send the page to somebody else, the same code runs in their browser. localhost then means their device, not yours.

A relative URL does not magically preserve your development backend either:

fetch ( ' /api/quote ' ); Enter fullscreen mode Exit fullscreen mode On a static host, this normally asks that host for /api/quote. If no such endpoint exists, the page may receive a 404 or an HTML fallback instead of JSON.

For a self-contained demo, replace the request with explicit sample data and keep the simulated behavior visible. For live data, deploy an endpoint your visitors can reach, then test its response and CORS policy from the public page.

// Simplified anti-example: never publish a real privileged credential here. const response = await fetch ( ' https://api.example.com/private-data ', { headers: { Authorization: ' Bearer SERVER_ONLY_KEY ' } }); Enter fullscreen mode Exit fullscreen mode Every visitor can download the page and inspect its scripts. Obfuscation changes how the credential looks; it does not establish a secret boundary.

Before publishing, inspect the actual export directory rather than only the project root. A bundler can copy a secret into its output even when.env itself is excluded. Check inline scripts, source maps, generated configuration, fixtures, and comments too. Remove private customer data at the same time.

If a privileged API call is required, keep that credential on a server. The browser calls your limited endpoint; your endpoint validates the request and calls the upstream service:

// Server-side route sketch. Add authentication, validation, and rate limits for a real service. export async function GET () { const upstream = await fetch ( ' https://api.example.com/private-data ', { headers: { Authorization: `Bearer ${ process. env. SERVICE_API_KEY } ` } }); if (! upstream. ok ) { // Do not pass an upstream secret or sensitive response through by default. return Response. json ({ error: ' Upstream request failed ' }, { status: 502 }); } return Response. json ( await upstream. json ()); } Enter fullscreen mode Exit fullscreen mode Some client-side API identifiers are deliberately public and can be restricted by origin or scope.

That is a provider-specific design, so follow the provider's documentation. Do not treat a server credential as public just because the variable name contains KEY.

A local file, a development server, and a public HTTPS page are different environments.

Also check for http:// dependencies in an HTTPS page. Browsers restrict mixed content, and fetch() requests to insecure resources can fail. Camera, microphone, service worker, and modern clipboard features have additional secure-context and permission requirements. http://localhost receives special treatment for development, which can hide a deployment problem.

Feature detection is more useful than assuming the preview and the public page have the same capabilities:

if ( window. isSecureContext && navigator. clipboard?. writeText ) { await navigator. clipboard. writeText ( text ); } else { // Show selectable text and a clear manual-copy instruction. showManualCopy ( text ); } Enter fullscreen mode Exit fullscreen mode 5. Make the static/backend split explicit A static page is a good fit when the result depends on the current visitor's input and public assets: a calculator, a proposal preview, a chart from bundled data, or a small editing tool whose output can be downloaded.

Add a backend when the product needs shared state or authority: submissions that another person must read, accounts and permissions, shared edits, private upstream credentials, privileged actions, or durable data across visitors and devices.

Before sharing the page, run this short review:

The goal is not to add a backend to every generated page. It is to make the page honest about where computation, data, and authority live. Once those boundaries are clear, static hosting can stay simple without pretending to provide server behavior.

Quelle: dev.to (dev.to). Original öffnen