Step 13: Generate Frontend Code

Phase: implement

Context

You have all project details: app_spec, project_id, anon_key, api_url, tables_created, rls_configured, selected_templates, and selected_patterns.

Now generate the complete client-side application.

What to do

Generate all the files for the user's app. The app must:

  • Be a complete, working single-page application (HTML + CSS + JavaScript)
  • Work in any modern browser without build tools, compilation, or npm
  • Use the run402 REST API for all data operations
  • Include all necessary API configuration (project_id, anon_key, api_url)

If using a template

Start from the template at /templates/{category}/{template-name}/. Read the template's index.html and customize:

  1. Replace placeholder values ({{ANON_KEY}}, {{API_URL}}, {{APP_NAME}}) with actual values
  2. Apply the user's customizations from app_spec
  3. Adjust colors, labels, and content to match what the user described

If building from patterns

Assemble the app from common patterns at /templates/patterns/:

  1. Start with responsive-layout.html as the page structure
  2. Add db-connection.js for API setup
  3. Add crud.js for data operations
  4. Add auth-flow.js if auth is needed
  5. Add file-upload.js if file uploads are needed
  6. Add polling.js if near-real-time updates are needed
  7. Write custom UI components specific to the app

API integration patterns

Configuration block (top of JavaScript)

const CONFIG = {
  API_URL: 'https://run402.com',
  ANON_KEY: '{anon_key}'
};
// Note: project_id is not needed in client-side code.
// The anon_key JWT routes requests to the correct project automatically.

async function api(path, options = {}) {
  const res = await fetch(CONFIG.API_URL + path, {
    ...options,
    headers: {
      'apikey': CONFIG.ANON_KEY,
      'Content-Type': 'application/json',
      ...options.headers
    }
  });
  if (!res.ok) throw new Error(await res.text());
  return res.json();
}

Read data

// Get all todos, newest first
const todos = await api('/rest/v1/todos?order=created_at.desc');

// Get todos for current user
const myTodos = await api('/rest/v1/todos?user_id=eq.' + userId);

// Search with filters
const urgent = await api('/rest/v1/todos?done=eq.false&order=created_at.desc&limit=10');

Write data

// Create
await api('/rest/v1/todos', {
  method: 'POST',
  headers: { 'Prefer': 'return=representation' },
  body: JSON.stringify({ task: 'Buy groceries', user_id: userId })
});

// Update
await api('/rest/v1/todos?id=eq.' + todoId, {
  method: 'PATCH',
  body: JSON.stringify({ done: true })
});

// Delete
await api('/rest/v1/todos?id=eq.' + todoId, { method: 'DELETE' });

Auth (if needed)

// Signup
const { id, email } = await api('/auth/v1/signup', {
  method: 'POST',
  body: JSON.stringify({ email, password })
});

// Login
const { access_token, refresh_token, user } = await api('/auth/v1/token?grant_type=password', {
  method: 'POST',
  body: JSON.stringify({ email, password })
});

// Use access_token for authenticated requests
headers: { 'Authorization': 'Bearer ' + access_token }

File structure

Generate a single index.html file with inline CSS and JavaScript. This is the simplest approach and works perfectly for deployment. If the app is complex, you may split into:

  • index.html — page structure
  • style.css — styles
  • app.js — application logic

Quality checklist

  • Does the app work without any build step?
  • Are all API URLs and keys correctly set?
  • Does the UI match what the user described?
  • Is it mobile-friendly (if requested)?
  • Are error states handled (show friendly messages, not technical errors)?
  • Does auth flow work if auth is enabled (signup, login, logout, protected routes)?

What to tell the user

"I've built your app! Let me deploy it so you can try it out."

Expected output

  • app_files — Array of file objects ready for deployment:
    [
      {"file": "index.html", "data": "...", "encoding": "utf-8"},
      {"file": "style.css", "data": "body { ... }", "encoding": "utf-8"},
      {"file": "app.js", "data": "const CONFIG = ...", "encoding": "utf-8"}
    ]

Memory directive