The Complete Guide
How to use every rakit.io feature — from the editor, AI Builder and database to serverless functions — plus a cheat sheet for writing instructions to the AI.
/api/db API.
Backend codeServerless functions, API reference & code examples.
Writing promptsThe prompt formula & ready-to-copy examples.
Having trouble?Common causes & how to fix them.
Feature Guide
Get to know every part of the rakit.io editor: where it is, what it's for, and how to use it step by step. In the editor, the ⓘ button next to each feature also opens a short explanation.
F1Getting Started & the Editor
From signing up to knowing where every button on the screen is.
Sign up & log in
- Open the rakit.io home page and click Sign up. Fill in a username, email and password — or choose Continue with Google.
- Right after signing up, your first website is live at
yourname.rakit.ioand the editor opens automatically. - New accounts get a one-time AI credit bonus, plus free credits every day (see Credits & Plans).
Two editor layouts: Simple & Coding
Choose with the switch at the top center. Your choice is remembered in the browser.
✦ Simple
Just the AI chat and the preview. Great when you'd rather describe things to the AI and see the result without touching code.
</> Coding
The full layout: file panel, code editor, database, functions, diagrams, history and console. Features that need this layout switch you to Coding automatically.
Screen map (Coding layout)
| Area | What's there |
|---|---|
| Top bar, left | Logo, file panel button, the website address chip (folder button = switch/create project, site link, copy URL button). |
| Top bar, center | The Simple / Coding switch and the save status. |
| Top bar, right | Preview (show/hide), Guide, Publish (only in manual publishing mode), View site, the plan badge, and your avatar (account menu). |
| Left panel | The project's files & folders, new file/folder buttons, image upload, and quota usage. |
| Center area | Tabs Code · AI · Data · Diagram · Functions · History · Console. The ⓘ button explains the open tab. |
| Right panel | Website preview, screen size options, Select blocks, and Edit (text & images). |
Avatar menu (top right corner)
| Item | What it does |
|---|---|
| Open public website · Copy website URL | Opens or copies the address of the active project's website. |
| Publishing mode | Choose live instantly or manual (dev/prod) — see Publishing. |
| Save all | Saves every open file that has unsaved changes. |
| Settings | Light/dark theme, language, and AI code prediction. |
| Bahasa Indonesia / English | Switch the interface language. |
| Subscription & AI credits | See plans, buy credits, or subscribe. |
| Log out | Log out of your account in this browser. |
F2Projects — Many Websites in One Account
Each project is a separate website with its own address, files, database, version history and AI conversations.
Creating a new project
- Click the folder button in the website address chip (top left).
- Choose New project.
- Enter the website address (lowercase letters, digits,
-), e.g.bakery→bakery.rakit.io. - Enter a project name (optional), then Create project.
Switch, rename, delete
- Switch project: click the folder button and pick a project from the list.
- Rename project…: changes the display name (the address stays).
- Delete this project…: deletes its files, database and history. Your last project can't be deleted.
| Item | Details |
|---|---|
| Number of projects | At most 5 per account. |
| AI credits | Belong to the account and are shared by all projects. |
| File & database quota | Counted per project (size depends on your plan). |
| Running AI prompts | One prompt at a time per account, in any project. |
F3Files, Folders & Images
Every part of your website is stored as a file in the left panel. index.html is the home page.
Creating & managing files
- The New file / New folder buttons above the file list. Type a full path to create inside a folder, e.g.
css/style.css. - Right-click (or the ⋯ button) on a file: Open, Preview this page, Copy public URL, Rename (F2), Delete (Del).
- Right-click on a folder: New file, New folder, Upload images to that folder.
- The Reload and Collapse all folders buttons are right next to them.
Uploading images
- Click the Upload images button, right-click → Upload images…, or drag files straight into the file list.
- Formats:
.png .jpg .jpeg .gif .webp .svg .ico .avif— the file contents are checked, so other files with a renamed extension are rejected. - Names are tidied automatically (lowercase, spaces →
-). If the name already exists: Replace, Save as new, or Skip.
Using images on a page
Click an image in the file panel to view it (pixel & file size), then copy its path, the <img> tag, or the CSS url().
<img src="/images/logo.png" alt="Bakery logo">.hero { background-image: url('/images/hero.jpg'); }| Limit | Free | Pro | Unlimited |
|---|---|---|---|
| One code file | 512 KB (.html · .css · .js) | ||
| One image | 1 MB | 5 MB | 10 MB |
| Total storage per project | 20 MB | 100 MB | 250 MB |
| Files & folders | 500 | 2,000 | 5,000 |
F4Code Editor
A VS Code-style editor for changing HTML, CSS and JavaScript directly.
Saving
- Auto-save (the switch below the editor): saves as you type, and the preview updates too.
- Ctrl/⌘ S saves the active file · avatar menu → Save all.
- When you close a tab with unsaved changes, you're asked: Save / Don't save / Cancel.
Code prediction (AI) — free
- Pause typing for a moment → the AI suggests the continuation in gray text.
- Tab accepts · Esc or keep typing to ignore.
- Uses no credits (there's a daily limit). Turn it off in Settings.
Right-click → ✦ AI
- Select a few lines of code, then right-click:
- ✦ Ask AI to change this code — puts that code in the AI box.
- ✦ Ask AI about this code — for an explanation.
- The request isn't sent right away; you can complete it first.
Search & navigation
- Ctrl/⌘ F finds in the file · Ctrl/⌘ B shows/hides the file panel.
- The breadcrumb above the editor shows where the file is.
- The bottom bar: cursor position and the file's language.
📖 Code Walkthrough — the AI explains your code (free)
The Code Walkthrough button above the editor (for .html, .css and .js files) opens an explanation panel next to the editor. The AI explains the code in the order it runs, not line by line.
- Open a file and click Code Walkthrough. Wait while the AI puts the steps together.
- Each step has a title, a kind (start, decision, loop, waiting for action, request…), the lines involved, an explanation, a real-value example, and key terms (click one to see its meaning).
- Click a step → its lines are highlighted in the editor. Click a line in the editor → its step opens. Use the ‹ › buttons, ▶ (autoplay), or the arrow keys.
- Steps that refer to another file (a page, a CSS class, an
/api/fn/…function) can be clicked to open it, then ← Back. - Also see the flow diagram, notes (bugs, needs checking, suggestions) and code speed. Use Ask the AI to ask about the open step.
F5Preview, Select Blocks & Edit
See your website the way visitors do, at different screen sizes.
| Control | What it does |
|---|---|
| Address field | Change the page path (e.g. /about) and press Enter to open another page. Esc cancels. |
| Desktop · Tablet · Phone | Changes the preview width: full, 768 px, or 390 px — to check the responsive layout. |
| ↻ Reload | Reloads the preview. |
| ↗ Open in a new tab | Opens the previewed page in a new browser tab. |
| DEV badge | Shown in manual publishing mode: the preview shows the dev version, not the public website. |
| Ctrl/⌘ \ | Show/hide the preview panel. |
🎯 Select blocks — change only specific parts
Instead of describing “the part below the second heading…”, point at it directly in the preview.
- Click Select blocks above the preview.
- Hover over the page, then click the part you want to change (max. 5 blocks, across several pages if you like — change pages with the links in the preview).
- Click Write instruction. The selected blocks appear above the AI box.
- Write the change, e.g. “make it 3 columns and add icons”, then send. The AI focuses on those blocks and leaves the rest alone.
- Click Done to leave selection mode.
✏️ Edit — change text & images right in the preview
For changing headings, paragraphs, button labels, list items or images without opening the code and without using AI credits.
- Click Edit above the preview.
- Hover over the page — editable text gets a blue box — then click the text and type.
- Press Enter or click elsewhere to save. Esc cancels.
- Click Done to leave edit mode.
The change is written to that page's HTML file (e.g. index.html) at exactly the same spot — formatting such as bold or links inside the text is kept. The file also opens in the Code tab, so you can undo with Ctrl/⌘ Z. Text written by JavaScript (e.g. the message 'Password must be at least 6 characters.' in script.js) can be changed too — the string is replaced in that JS file. Text assembled from data (e.g. “You've clicked 3 times”) can't: clicking it shows a red marker, so change it in the code or ask the AI. To change pages: Alt+click a link.
Replacing images: in Edit mode, click the image. Pick another image from the project, click Upload a new image…, or paste an image address (https://…). Also fill in the alt text — a short description of the image for screen readers and search engines — then Save. Only <img> images can be replaced here; CSS background images and <picture> images with several versions are changed in the code or with the AI.
F6AI Assistant (Builder & Plan)
Open the AI tab or press Ctrl/⌘ I. Prompt-writing techniques are in Part 2.
🔨 Builder
The AI writes/changes/deletes files and creates database tables directly.
- Choose Builder below the prompt box.
- Write your request and press Enter (Shift+Enter = new line).
- Watch the progress & the list of changed files. Click a file to see the differences.
- Choose Save to accept or Undo to roll everything back.
🧭 Plan
The AI only discusses & drafts a plan, without changing files.
- Choose Plan and describe your idea.
- Go back and forth until the plan is right.
- Press Run this plan — the AI switches to Builder and carries it out.
Prompt box features
| Feature | How to use it |
|---|---|
| 📎 Attach images | The Image button, paste (Ctrl/⌘ V), or drag files. Max. 3 images (JPG/PNG/WEBP, max. 2 MB) — a design example, a sketch, or a screenshot of an error. Prompts with images use 2 credits. |
| 🎯 Selected blocks | From Select blocks. Remove one with the × button on its chip. |
| ⏹ Stop | Stops the AI midway. The credits are refunded. |
| Prompt length | Max. 20,000 characters. |
Conversations & history
- 🕘 Conversation history (clock icon): open an old conversation to continue it.
- ↻ New conversation: start a new topic. The AI doesn't carry over the previous chat, so it's cheaper and more focused.
- 🗑 Delete all history: deletes every conversation in this project.
- History is stored on the server (max. 50 conversations, deleted after 90 days of inactivity).
“✦ … with AI” buttons in other features
Many features have a ✦ button that fills the AI box with a request plus its context (it isn't sent right away):
| Where | Example buttons |
|---|---|
| Functions | Create with AI, Change, Fix with AI (from a failed log/test) |
| Database | Use the table on the website, Build a form with AI |
| Diagram | Fix findings with AI |
| Console | Fix with AI on an error line |
| Code editor | Right-click → change / ask about the selected code |
| Feature explanation (ⓘ) | Try it now — an example prompt for that feature |
F7Database (Data Tab)
Store visitor data & content permanently — like a spreadsheet, ready to use from your web pages.
Creating a table
- Open the Data tab and click + (New table) or + Create table.
- Enter a table name (e.g.
messages), then add columns: a name, a type, tick Required if it must be filled, and Private if visitors must not see it. - Click Create table. The
idandcreated_atcolumns are created automatically.
Column types
| Type | For | Example value |
|---|---|---|
| Text | Names, messages, addresses (max. 10,000 characters) | Budi |
| Number | Prices, quantities, scores | 150000 |
| Yes/No | Attending, agreed, paid | true / false |
| Date | Birthdays, event schedules | 2026-12-31 or 2026-12-31T19:00 |
| Relation | Points to a row in another table (e.g. order → product) | 12 (the target row's id) |
| Image | Product photos, avatars, payment receipts | /uploads/products/abc.jpg |
Access: who may do what
Click Settings on a table. Each operation can be Public (every visitor) or Only you (the owner, through the editor). By default everything is Only you.
| Operation | Meaning | Usual advice |
|---|---|---|
list | Read a list of records | Public for guestbooks, catalogs, leaderboards |
view | Read one record | Public for product detail pages |
create | Add records | Public for contact forms, RSVPs, orders |
update | Change records | Only you (visitors are anonymous) |
delete | Delete records | Only you |
Private columns are never sent to visitors even when list is public — good for emails, phone numbers and addresses.
Managing table contents
- + Row adds data by hand. Double-click a cell to edit it. The trash icon deletes a row.
- Image columns show a thumbnail; double-click to upload, replace or clear it (you can also paste an
https://…address). - Lots of data is split into pages — use the Previous / Next buttons.
- The Use on your website section shows ready-to-copy example code (reading, adding, updating, deleting, handling errors) and flags access that isn't public yet.
- Delete table is in the table settings — click once more to confirm.
Using the database from your website code
| Request | What it does |
|---|---|
GET /api/db/<table>?sort=-created_at&limit=20&offset=0 | List rows → { rows, total }. Add &column=value to filter. |
GET /api/db/<table>/<id> | One row |
POST /api/db/<table> | Add a row (JSON body) |
PATCH /api/db/<table>/<id> | Update a row |
DELETE /api/db/<table>/<id> | Delete a row |
POST /api/db/<table>/upload?column=<column> | Upload an image for an Image column → { url } |
GET /api/db/<table>?expand=<relation_column> | Also fetch the data from the table a relation column points to |
// save
const res = await fetch('/api/db/messages', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, message }),
});
if (!res.ok) alert((await res.json()).error);
// show the 20 newest
const { rows } = await (await fetch('/api/db/messages?sort=-created_at&limit=20')).json();const up = await fetch('/api/db/products/upload?column=image', { method: 'POST', body: fileInput.files[0] });
const { url } = await up.json(); // e.g. "/uploads/products/lx3k-9f2a.jpg"
await fetch('/api/db/products', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, image: url }),
});create or update access is public.| Database limits | Free | Pro | Unlimited |
|---|---|---|---|
| Size per project | 10 MB | 50 MB | 100 MB |
| Tables · columns | 20 tables · 30 columns per table | ||
| Requests from visitors | 300 reads & 60 writes per minute per visitor · max. 20 uploads / 10 minutes | ||
F8Serverless Functions (Backend)
JavaScript code that runs on the server, not in the visitor's browser — for secret API keys, calculations that mustn't be tampered with, notifications, or calling other services.
Creating & trying a function
- Open the Functions tab and click + New function. Give it a name (lowercase letters, digits,
-or_, max. 40), e.g.send-message. - The file
functions/send-message.jsis created with example code. Click Open code to change it. - Click Try: choose a method, fill in the query & JSON body, then run it. The result, status, time and
console.logoutput appear right away. - Call it from your web pages at
/api/fn/send-message. Copy URL copies the full address.
What a function looks like
export default async function (req, { db, env, fetch, ai }) {
// req: { method, query, headers, body }
const row = await db.insert('orders', {
name: req.body.name, total: 150000,
});
return { ok: true, id: row.id }; // sent as JSON
}Calling it from a page
const res = await fetch('/api/fn/order', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Ani' }),
});
const data = await res.json();What's available inside a function
| Object | Use |
|---|---|
req | method, query, headers, body (already parsed if JSON). For scheduled runs, req.method is "CRON". |
db | The project database as the owner (public access rules don't apply): db.list(table, { sort, limit, offset, filter }), db.get, db.insert, db.update, db.delete. |
env | Secret values from Secrets (env), e.g. env.TELEGRAM_TOKEN. |
fetch | Calls external APIs (max. 10 per execution; can't call rakit.io websites — use db). |
ai | Uses AI with your own API key — see AI in Functions. |
| Response | Plain values are sent as JSON. For full control: new Response(text, { status, headers }) or Response.json(data, { status }). A thrown error → status 500 { error }. |
require, no npm packages, and no file access. Code in the functions/ folder can never be read by visitors.Full reference
| API | Details |
|---|---|
req.method | GET, POST, PUT, PATCH, DELETE… or CRON when run by a schedule. |
req.path | The path that was called, e.g. /api/fn/order. |
req.query | Object of URL parameters (values are text): /api/fn/search?q=cake → req.query.q. |
req.headers | Request headers (lowercase names). req.headers['x-client-ip'] = the visitor's IP. Cookies aren't forwarded. |
req.body | An object when the request sends JSON (Content-Type: application/json), otherwise raw text. Max. 1 MB. |
await req.text() · await req.json() | The body as text / parsed as JSON. |
db.list(table, { sort, limit, offset, filter }) | → { rows, total }. sort: '-created_at' (- = newest first), limit max. 100, filter: { status: 'new' } = column equals value. |
db.get(table, id) | One row (error if it doesn't exist). |
db.insert(table, data) | Adds a row → the new row with its id & created_at. |
db.update(table, id, data) | Changes only the columns you send → the updated row. |
db.delete(table, id) | Deletes a row → { ok: true }. |
env.NAME | Project secrets (max. 30 secrets, UPPER_CASE names). Not set → undefined. |
await fetch(url, { method, headers, body }) | Calls an external service. An object body is sent as JSON automatically. Result: ok, status, headers.get(name), await text(), await json(). Max. 10 calls, 8 seconds & 2 MB response per call. |
console.log/info/warn/error | Shown in Try, the Execution log, and the Console tab (BE). Objects are printed as JSON. console.time/timeEnd, count, table and assert are available too. |
return value | Status 200 + JSON. return with no value → status 204 (empty). |
Response.json(data, { status, headers }) | JSON with your own status, e.g. 400 for bad input. |
new Response(text, { status, headers }) | A text/HTML/CSV response. Allowed headers: content-type, cache-control, content-disposition, location, etag, access-control-*, and x-…. |
Response.redirect(url, 302) | Redirects the visitor to another address. |
throw new Error('…') | Status 500. In the dev version & tests the full message is shown; on the public website visitors only see “The function failed to run”, with details in the Log. |
Ready-to-use code examples
Copy into functions/<name>.js, adjust the table/column names, then test with the Try button.
export default async function (req, { db, env, fetch }) {
if (req.method !== 'POST') return Response.json({ error: 'Use POST' }, { status: 405 });
const { name, email, message } = req.body || {};
if (!name || !message) return Response.json({ error: 'Name and message are required' }, { status: 400 });
// the "messages" table can stay "Only you": db in a function works as the owner
const row = await db.insert('messages', { name, email, message });
// secrets: TELEGRAM_TOKEN & TELEGRAM_CHAT_ID (Functions tab → Secrets)
const tg = await fetch(`https://api.telegram.org/bot${env.TELEGRAM_TOKEN}/sendMessage`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: { chat_id: env.TELEGRAM_CHAT_ID, text: `New message from ${name}:\n${message}` },
});
if (!tg.ok) console.warn('Telegram failed', tg.status, await tg.text());
return { ok: true, id: row.id };
}export default async function (req, { db }) {
const { name, phone, items } = req.body || {}; // items: [{ id: 3, qty: 2 }, …]
if (!Array.isArray(items) || !items.length) {
return Response.json({ error: 'Your cart is empty' }, { status: 400 });
}
let total = 0;
const lines = [];
for (const it of items) {
const p = await db.get('products', it.id); // the price comes from the database, not the browser
const qty = Math.max(1, Math.min(99, Number(it.qty) || 1));
if (p.stock < qty) return Response.json({ error: `Not enough ${p.name} in stock` }, { status: 409 });
total += p.price * qty;
lines.push(`${p.name} x${qty}`);
await db.update('products', p.id, { stock: p.stock - qty });
}
const order = await db.insert('orders', { name, phone, items: lines.join(', '), total, status: 'new' });
return { ok: true, number: order.id, total };
}export default async function (req, { env, fetch }) {
const city = req.query.city || 'Jakarta';
const url = `https://api.openweathermap.org/data/2.5/weather?q=${encodeURIComponent(city)}`
+ `&units=metric&lang=en&appid=${env.OWM_KEY}`;
const res = await fetch(url);
if (!res.ok) return Response.json({ error: 'Weather data unavailable' }, { status: 502 });
const d = await res.json();
return Response.json(
{ city: d.name, temp: d.main.temp, weather: d.weather[0].description },
{ headers: { 'cache-control': 'public, max-age=600' } }, // cache for 10 minutes
);
}
// called from a page: fetch('/api/fn/weather?city=Bandung')export default async function (req, { db, env }) {
// a simple key for a private admin page (secret ADMIN_KEY)
if (req.headers['x-admin-key'] !== env.ADMIN_KEY) {
return Response.json({ error: 'Not allowed' }, { status: 401 });
}
switch (req.method) {
case 'GET':
return db.list('orders', { sort: '-created_at', limit: 50, filter: req.query.status ? { status: req.query.status } : {} });
case 'PATCH':
return db.update('orders', req.query.id, { status: req.body.status });
case 'DELETE':
return db.delete('orders', req.query.id);
default:
return Response.json({ error: 'Method not supported' }, { status: 405 });
}
}
// from a page: fetch('/api/fn/admin-orders?status=new', { headers: { 'X-Admin-Key': key } })export default async function (req, { db, env, fetch }) {
if (req.method !== 'CRON') return Response.json({ error: 'Schedules only' }, { status: 403 });
const since = Date.now() - 24 * 3600e3; // the last 24 hours (created_at is in UTC)
const today = new Date(Date.now() + 7 * 3600e3).toISOString().slice(0, 10); // WIB date for the title
const { rows } = await db.list('orders', { sort: '-created_at', limit: 100 });
const fresh = rows.filter((r) => Date.parse(r.created_at) >= since);
const revenue = fresh.reduce((n, r) => n + (r.total || 0), 0);
console.log(`Report ${today}: ${fresh.length} orders, Rp${revenue}`);
await fetch('https://api.resend.com/emails', { // send an email via Resend
method: 'POST',
headers: { Authorization: `Bearer ${env.RESEND_KEY}`, 'Content-Type': 'application/json' },
body: { from: 'shop@yourdomain.com', to: env.MY_EMAIL, subject: `Report ${today}`,
html: `<p>${fresh.length} orders, total Rp${revenue}</p>` },
});
}
// set it in the Functions tab → Schedule → "Every day at 21:00"export default async function (req, { db, env }) {
if (req.query.key !== env.ADMIN_KEY) return Response.redirect('/', 302); // not the owner → home page
const { rows } = await db.list('signups', { sort: 'id', limit: 100 });
const csv = ['id,name,email', ...rows.map((r) => `${r.id},"${r.name}","${r.email}"`)].join('\n');
return new Response(csv, {
headers: {
'content-type': 'text/csv; charset=utf-8',
'content-disposition': 'attachment; filename="signups.csv"',
},
});
}export default async function (req, { ai }) {
const history = (req.body?.messages || []).slice(-10); // [{ role: 'user'|'assistant', content }]
const { text } = await ai.chat({
system: "You are the support agent for Sari's Bakery. Open 8 am–8 pm. Answer briefly & kindly.",
messages: history,
maxTokens: 400,
});
return { reply: text };
}async function send(data) {
const res = await fetch('/api/fn/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
const result = await res.json().catch(() => ({}));
if (!res.ok) throw new Error(result.error || 'Sending failed'); // the message from Response.json({ error })
return result;
}400 with a clear message · never trust prices/totals from the browser · keep every key in Secrets · use console.log and check the output in Try or the Log · the time limit is 10 seconds, so avoid many sequential fetch calls.| Other limits | Value |
|---|---|
| Requests to one website | 120 per minute (all visitors) · 60 per minute per visitor |
Request body · fetch response | 1 MB · 2 MB |
| Console output per execution | 16 KB (the rest is cut off) |
| Dev version (manual publishing) | Dev functions are called at yourname--dev.rakit.io/api/fn/… and use the dev database |
Secrets, schedules and logs
🔑 Secrets (env)
Enter a name (e.g. TELEGRAM_TOKEN) and its value, then click Save. Read it in code with env.TELEGRAM_TOKEN. The value isn't shown in the editor again.
⏱ Schedules Pro / Unlimited
Click Schedule on a function: every 5/15/30 minutes, every hour, every day at a set time, every week, or a custom cron (WIB time, UTC+7). Most frequent: Pro every 15 minutes, Unlimited every 5 minutes.
📜 Execution log
The latest executions (triggered by visitors, tests or schedules) with status, duration, errors and console output. Failed executions have a ✦ Fix with AI button.
📊 Quota
The meter above the tab shows today's executions. Limits: 10 seconds & 64 MB per execution.
| Executions per day (WIB) | Free | Pro | Unlimited |
|---|---|---|---|
| All functions in the account | 1,000 | 20,000 | 100,000 |
F9AI in Functions (AI Providers)
Build AI features into your website — chatbots, summaries, data extraction, image checks — using your own API key.
Adding a provider
- Functions tab → the AI providers section → add a provider.
- Choose a type: OpenAI, Anthropic Claude, Google Gemini, or OpenAI-compatible (with quick buttons for DeepSeek, Groq, OpenRouter, Mistral and Together).
- Fill in a name (used in your code), the API key, a chat model, and an embedding model (optional). Mark one as the default.
- Click Save & test to make sure the key and model work. Max. 10 providers per project.
export default async function (req, { ai }) {
const { text } = await ai.chat(req.body.question, { system: 'You are a bakery support agent. Answer briefly.' });
const data = await ai.json('Extract the name & phone from: ' + req.body.message, { name: 'string', phone: 'string' });
const check = await ai.chat('Is this a payment receipt?', { images: ['/uploads/receipts/abc.jpg'] });
const [a, b] = await ai.embed(['chocolate cake', 'brownies']);
return { text, data, check: check.text, similar: ai.similarity(a, b) };
}| Call | Result |
|---|---|
ai.chat(prompt, { system, images, provider, model, temperature, maxTokens }) | { text, model, provider, usage } |
ai.json(prompt, shape) | An object in the requested shape |
ai.embed(text | [text]) | Vectors for meaning-based search (Anthropic has no embeddings) |
ai.similarity(a, b) | How similar two vectors are (0–1) |
ai.providers() | The installed providers (without keys) |
Limits: max. 5 ai.* calls per execution, 60 seconds per call, max. 4 images (5 MB). Time spent waiting for the AI doesn't count toward the function's 10-second limit. Usage per provider is shown in the Functions tab.
F10AI-Drawn Diagrams
The AI draws your website's structure from its files & database — to understand the big picture, for documentation, or for coursework.
| Type | Shows |
|---|---|
| Use Case | The actors and what they can do on the website |
| Activity | A visitor's main process flow, with decision branches |
| Sequence | The order of interactions Visitor → Page → API → database/external service |
| Class | Tables and JavaScript modules with their attributes, methods and relationships |
| State | How an important object's status changes (e.g. an order) |
| ERD | Tables, columns, types, required/private, and relationships |
| Site map | Pages, links between pages, CSS/JS files — broken links & missing files are marked |
| Data flow | Which pages/scripts/functions use which tables — requests that will be rejected are marked |
- Open the Diagram tab and choose a type.
- Click Update diagram — the AI draws it from the current state (uses 1 credit, refunded on failure). The diagram is saved and doesn't change by itself.
- Read the Findings panel: the AI's notes, such as tables anyone can delete or broken links.
- If the drawing fails to display, click Fix with AI (free, max. 2 times per diagram).
- Copy the Mermaid code or download it as SVG. The ⓘ button explains how to read the open diagram type.
Zoom & pan
| Zoom | Pan | |
|---|---|---|
| Mouse | Scroll wheel; double-click (Shift = zoom out) | Drag; Shift + scroll = horizontal |
| Touchpad | Pinch, or Ctrl/⌘ + scroll | Two-finger swipe |
| Touchscreen | Two-finger pinch | One-finger drag |
| Keyboard | + / −, 0 fit to screen, 1 actual size | Arrow keys |
F11Version History
A “save point” for all your project files. Experiment without fear of breaking things.
When versions are saved
- Automatically when you start editing (at most every 10 minutes).
- Automatically before the AI changes files.
- Automatically before restoring a version (so even a restore can be undone).
- Manually: the Save version now button, with your own name, e.g. “before redesign”.
Restoring
- Open the History tab and choose a version.
- Look at the files labeled Changed, Deleted, or New file. Click View differences.
- Restore this file for one file, or Restore this version for the whole project.
| History limits per project | Free | Pro | Unlimited |
|---|---|---|---|
| Kept for | 7 days | 30 days | 90 days |
| Number of versions | 20 | 200 | 2,000 |
History doesn't count toward your storage quota.
F12Console — Finding the Cause of Errors
Every message from your website in one place. A red number on the tab means new errors.
| Source | What's in it |
|---|---|
| FE (frontend) | console.log output and errors from pages in the preview |
| BE (backend) | Logs and errors from serverless functions |
| Network | Requests from pages to the server (e.g. fetch('/api/db/products')) with their status |
| System | Notes such as pages being loaded |
- Filter by source, tick Errors only, or type in Search logs….
- The ↻ button reloads the preview, 🗑 clears the log.
- On an error line, click ✦ Fix with AI — the error message is sent along as context.
| Status | Meaning |
|---|---|
| 2xx | Success |
| 4xx | Request rejected — e.g. 403 table access isn't public yet, 404 table/page doesn't exist, 400 invalid data |
| 5xx | An error on the server/in a function |
F13Publishing: Live or Dev/Prod
Control when visitors see your changes. Open the avatar menu → Publishing mode.
⚡ Live instantly default
Every change appears on yourname.rakit.io right away. Great for learning and experimenting.
🚀 Manual publishing (dev/prod)
You edit the dev version at yourname--dev.rakit.io (you can share it to get feedback). The public website only changes when you press Publish. The dev database is separate, for testing.
Publishing changes
- A dot on the Publish button (top right) means there are changes that aren't live yet.
- Click the button — you'll see the list of new, changed and deleted files, plus database structure changes.
- Click Publish. Data & images submitted by visitors on the public website stay safe; dev test data isn't copied.
- If a table/column will be deleted, tick the confirmation first — its data will be removed from the public website.
F14AI Credits, Plans & Payment
The credit badge in the AI panel shows your remaining credits. Click it, or open the avatar menu → Subscription & AI credits.
What does each feature cost?
| Feature | Cost |
|---|---|
| AI prompt (Builder / Plan) | 1 credit |
| Prompt with images | 2 credits |
| Update diagram | 1 credit |
| Code prediction, Code Walkthrough, diagram fixes | Free (with a daily limit) |
AI in functions (ai.*) | Billed by the provider to your API key, not rakit.io credits |
| Failed / stopped prompts / full queue | Credits are refunded |
Where credits come from (used in this order)
- Subscription quota — if you subscribe to Pro/Unlimited.
- The welcome bonus for new accounts (one-time), then daily free credits — reset at 00:00 WIB (UTC+7); leftovers don't accumulate.
- Purchased credits — never expire.
Plans
| Free | Pro | Unlimited | |
|---|---|---|---|
| AI | Daily free credits | A credit quota every 30 days | No monthly quota, with a daily prompt limit |
| File storage / project | 20 MB | 100 MB | 250 MB |
| Database / project | 10 MB | 50 MB | 100 MB |
| Files & folders | 500 | 2,000 | 5,000 |
| Image size | 1 MB | 5 MB | 10 MB |
| Version history | 7 days / 20 | 30 days / 200 | 90 days / 2,000 |
| Function executions / day | 1,000 | 20,000 | 100,000 |
| Function schedules | — | min. 15 minutes | min. 5 minutes |
Current prices and AI quotas are shown in the Subscription & AI credits menu.
Paying with QRIS
- Choose a credit package or a subscription, then click pay.
- Scan the QRIS code with any Indonesian banking or e-wallet app that supports QRIS.
- Keep the payment window open — the credits/plan activate automatically as soon as the payment is received.
- 30-day subscriptions, paid once with no automatic billing.
- Renewing the same plan adds 30 days from its end date.
- Upgrading Pro → Unlimited: active immediately; the remaining Pro days are converted by price.
- When a subscription ends, limits go back to Free. Files aren't deleted, but new/larger files are rejected until usage is below the limits.
F15Settings & Keyboard Shortcuts
Avatar menu → Settings. Settings are saved in the browser you're using.
Appearance & language
Light (cream paper) or Dark theme. The code editor and diagram colors follow along. Choose Bahasa Indonesia or English for the interface — the AI's explanations, diagrams and messages follow that language too.
Code editor
Automatic code prediction (AI) — turn the gray code suggestions on or off.
| Shortcut | Action |
|---|---|
| Ctrl/⌘ S | Save file |
| ⌥ ⌘ S | Save all |
| Ctrl/⌘ F | Find in file |
| Ctrl/⌘ B | Show/hide the file panel |
| Ctrl/⌘ \ | Show/hide the preview |
| Ctrl/⌘ I | Open the AI Assistant |
| Enter · Shift Enter | Send prompt · new line |
| Tab · Esc | Accept · ignore a code prediction |
| F2 · Del | Rename · delete the selected file |
| ← → | Move between steps in Code Walkthrough |
F16Common Problems & Fixes
Check here first before getting stuck.
| Problem | Cause & fix |
|---|---|
| A form doesn't save and the Console shows 403 | The table's create access is still “Only you”. Open the Data tab → Settings → make it Public. |
| Data doesn't show up, status 404 | The table name in the code differs from the one in the Data tab (watch letters & underscores). |
| The email column doesn't show on the page | Columns marked Private are never sent to visitors. View them in the Data tab. |
| An image doesn't show | Wrong path (upper/lowercase matters). Click the image in the file panel → copy its path. |
| Changes don't appear on the public website | Manual publishing mode is on — press Publish. Or the file hasn't been saved. |
| The AI's result isn't what you wanted | Press Undo, then rewrite your request more specifically, or use Select blocks. You can also go back via the History tab. |
| “The AI is at capacity” | The queue is busy; your credits are refunded. Try again shortly. |
| Out of credits | Wait for the 00:00 WIB (UTC+7) reset, buy credits, or subscribe. |
| A file/image is rejected because of the quota | Delete unused files, shrink images, or upgrade your plan. |
| A function errors / times out | Check the Execution log in the Functions tab, then ✦ Fix with AI. Make sure the secrets (env) it uses are set. |
| A button does nothing when clicked | Open the Console tab → filter FE → read the red error → ✦ Fix with AI. |
Prompt Cheat Sheet
How to write instructions for the AI Builder so the result is right on the first try — with ready-to-copy examples.
1Basics — How the AI Works
Understand the two modes & three golden rules to get it right on the first try.
🧭 Plan mode
The AI only drafts a plan — it doesn't touch files. Great for new projects or fuzzy ideas. Finish by pressing “Run this plan”.
🔨 Builder mode
The AI creates/changes files and database tables directly. Great for building, changing or fixing.
Three golden rules
- State the goal, not just the name. “A website for a home bakery that takes orders online” is far better than “a bakery website”.
- List the parts one by one. Which pages, what goes in each section, what data to save.
- One prompt = one big change. For different things, send separate prompts so they're easy to fix and save credits.
[Type of site] for [who/what for], with [sections], in a [color/mood] style, and [data to save]
2Structure & Pages
Deciding the files, pages and navigation.
Layout from scratch
Adding a page
3Design & Visual Style
How to describe colors, fonts and mood effectively.
| What you want | How to write the prompt |
|---|---|
| Specific colors | main color #2563eb, cream background #fef9f3 |
| Overall style | clean & professional corporate style / playful & cheerful |
| Font | the "Plus Jakarta Sans" font from Google Fonts |
| Dark theme | dark mode with a theme toggle button |
| Animation | fade-in animation as the page scrolls |
| Icons | icons from Lucide (via CDN) |
Icons & illustrations
Dark theme
<script> or <link>. Say so clearly, e.g. “use Bootstrap 5 from a CDN”.4Responsive Design — Desktop / Mobile
How to ask for different layouts on phones and desktops, or lock to one of them.
Choose a direction
Responsive (both)
The layout adapts to the screen. No need to ask — this is the default.
Desktop-only
The page is designed for wide screens (e.g. dashboards, data tables).
Mobile-only
Designed specifically for phone screens (e.g. an attendance app, a calculator).
Desktop-only
The page is made for wide screens. Phone visitors see an “open on desktop” message.
Mobile-only
Designed for phones: big buttons, one column, bottom navigation.
Different behavior per screen size
If you want elements to appear/disappear or change shape at certain sizes:
Hide on phones
Change shape
Adaptive columns
Tables become cards
Screen sizes (common breakpoints)
If you want to give exact numbers, use these as a reference:
| Device | Screen width | Say in your prompt |
|---|---|---|
| 📱 Phone | < 640px | on phones (below 640px) |
| 📱 Large phone / small tablet | 640–767px | on medium screens |
| 💻 Tablet | 768–1023px | on tablets (768–1023px) |
| 🖥️ Desktop | ≥ 1024px | on desktop (1024px and up) |
| 🖥️ Wide desktop | ≥ 1280px | on wide screens |
| Need | How to write the prompt |
|---|---|
| Lock to desktop | this page is desktop-only, show an "open on a computer" message on phones |
| Lock to mobile | make it phone-only, max width 480px, centered on desktop |
| Specific elements | hide the statistics section on phones |
| Menu | horizontal menu on desktop, hamburger on phones |
| Catalog grid | 4 columns desktop, 2 tablet, 1 phone |
| Images | images scale to the width and never overflow the screen |
| Font | smaller headings on phones (24px), larger on desktop (40px) |
| Orientation | place them side by side when the screen is horizontal (landscape) |
| Testing on phones | make sure nothing overflows the screen or needs sideways scrolling |
Example: desktop-only dashboard
Example: mobile-only app
5SEO & Social Sharing
So your site shows up on Google and looks great when its link is shared on WhatsApp/social media.
Title & description (Google)
Share previews (Open Graph)
Tab & device icons
Language & search engines
A complete SEO request
| Need | How to write the prompt |
|---|---|
| Show up on Google | optimize SEO so it appears in Google search, add page titles and descriptions |
| Tidy links on WhatsApp | make a nice preview when the link is shared on WhatsApp and social media |
| Favicon | add my logo as the favicon in the browser tab |
| Keywords | naturally include "jakarta bakery" and "order cakes online" |
| Google Maps | add the shop location in a way Google can read (address, opening hours) |
| Multiple pages | make sure every page has its own title & description |
6Accessibility — Easy for Everyone to Use
Making your site comfortable for anyone, including screen reader users and people with visual impairments.
Images & alt text
Contrast & readability
Usable without a mouse
Clear forms
7Forms & Input Validation
A good form saves data neatly and tells visitors when something's wrong.
A complete form
Choice & date fields
Uploading files & images
Showing incoming data
8Animation & Advanced Interaction
Dynamic touches that make your site feel alive — without getting in the way.
Scroll animations
Hover effects
Gallery & lightbox
Tabs & accordions
Notifications & toasts
Dark/light mode
9Images, Media & Icons
How to ask for images, illustrations, maps, videos and icons without your own files.
Temporary images (placeholders)
Icons
Illustrations
Location map
YouTube video
Keep it fast
10Navigation & Multiple Pages
Organizing many pages and the links between them neatly.
about.html can be opened at /about.
A custom 404.html page is also used automatically when a page isn't found.
Navigation menu
Your own 404 page
Bottom navigation (phones)
In-page links
11Performance & Speed
A fast site is more pleasant to use and better liked by search engines.
Light & fast
Fast fonts
Lean images
Loading indicators
12Content & Writing
The AI can write the text too — tell it who's reading.
Tone of voice
Target readers
Key parts
Sample content
13Security & Personal Data
Protecting visitors' data and keeping it from being misused.
| Need | How to write the prompt |
|---|---|
| Sensitive data | mark email, phone number and address as private data — only I can see them |
| Public forms | visitors may only submit; they can't see other people's submissions |
| Anti-spam | add a "type the answer to 3+2" field to stop bots from submitting the form |
| Don't lose data | save all visitor data to the database, not just in the browser |
| Passwords | if there's a private area, don't store passwords on the site — keep it owner-only |
| API keys / tokens | keep the Telegram token in a serverless function, read it from env.TELEGRAM_TOKEN — never write it in a page |
| Prices can't be tampered with | calculate the order total in a serverless function, not in the browser |
14Third-Party Integrations (CDNs & Services)
Adding popular services through a CDN/link — no server of your own needed.
| Need | Prompt |
|---|---|
| Charts & statistics | show a monthly sales chart with Chart.js from a CDN |
| Maps | embed Google Maps for the location 10 Merdeka St. |
add a floating WhatsApp button to the number +62812xxxx | |
| Instagram/social | add links to Instagram @myshop and Facebook |
| Video | embed the YouTube video youtube.com/watch?v=xxxx responsively |
| UI framework | use Bootstrap 5 from a CDN for the layout |
| Dates | use a tidy date picker that's easy to use on phones |
| Event calendar | show a monthly calendar for picking a visit date |
| Telegram notifications | create a serverless function that sends a Telegram message for every new order (token in env.TELEGRAM_TOKEN) |
| Other services' APIs | create a function that fetches exchange rates from an external API, keep the API key in secrets |
| Your own AI features | create a function that summarizes customer reviews with ai.chat (my default provider) |
| Automatic reports | create a daily sales report function; I'll schedule it for 07:00 every day |
15Data Tables & Dashboards
Showing lots of data neatly, plus number summaries and charts.
Tables with sorting & search
Number summaries
Charts
Add/edit/delete
16Advanced Prompt Patterns
Techniques for more precise results, especially on complex sites.
Step-by-step iteration (from plan to result)
Context + request
Give an example
Say what you don't want
Point to a specific part
Ask for targeted fixes
When the result isn't quite right
| Problem | Fix-up prompt |
|---|---|
| Messy layout | tidy up the services section: align the icons, titles and descriptions neatly |
| Colors don't fit | change the yellow accent to light blue, keep everything else |
| Too crowded | simplify: add space between sections, remove some elements |
| A feature errors | nothing happens when the button is clicked. Check and fix it |
| Not responsive yet | the layout breaks on phones. Fix it so it's tidy on small screens |
| Want variations | make 3 hero style options, I'll pick one |
17Database — Save & Show Data
rakit's main strength: your site can save data without a server of your own. The AI creates the tables automatically.
fetch('/api/db/table_name') — no API key, no CORS.
Don't use localStorage for data visitors submit, because localStorage only exists in one person's browser.
Common patterns: pick the one you need
| Type of site / feature | Prompt | Table access |
|---|---|---|
| Guestbook / comments | Build a guestbook: a name & message form with the latest messages listed below it. |
public: list, create |
| Contact / sign-up form | Build a contact form (name, email, message). Only the owner may read the submissions. |
public: create + private email |
| Event registration / RSVP | A seminar registration form: name, email, organization, number of attendees. |
public: create |
| Product catalog | Build a product catalog (name, price, description, image) shown on the page for everyone to see. |
public: list |
| Poll / voting | Build a poll: save each visitor's choice and show the results as percentages. |
public: list, create |
| Scoreboard / leaderboard | Save player scores (name, score) and show the top rankings. |
public: list, create |
| Orders | An order form: name, phone, address, items, total. Only the owner may see the list of orders. |
public: create + private data |
| Product reviews / ratings | Build reviews with a name, a 1–5 star rating, and a comment. |
public: list, create |
Name the column types
Want to see the data yourself?
Visitors are anonymous (they have no account). So keep
update/delete owner-only — you view &
manage the data in the Database tab of the editor.
18Interaction & JavaScript Features
Dynamic behavior: filters, search, carts, calculators and more.
Search & filters
Shopping cart
Calculator
Slider / carousel
Modal / popup
Upload & show images
19Complete Prompt Examples (Ready to Use)
Just copy, adjust the names & details, and send it in Builder mode.
20Fixing & Changing
How to correct a result without starting from scratch.
| Situation | Prompt |
|---|---|
| Result not quite right | Fix the hero section: the text is too small and the button doesn't stand out. Make them bigger and higher-contrast. |
| Change colors | Change every green to navy blue, keep the rest. |
| Change content | Change the heading to "Welcome to Our Shop" and make the text friendlier. |
| Rearrange | Move the testimonials section below the pricing section. |
| Add a feature | Add a floating WhatsApp button in the bottom right corner. |
| Fix an error | The form doesn't save when submitted. Check and fix it so the data goes into the database. |
| Tone it down | It's too busy. Simplify: fewer colors, more white space. |
21Limits & Technical Tips
What to know so you don't hit a wall.
| Aspect | Limit |
|---|---|
| File types | .html · .css · .js + uploaded images |
| Size per code file | Max 512 KB |
| Total per project | 20 MB & 500 files/folders (more on the Pro/Unlimited plans) |
| Length of one prompt | Max 20,000 characters, max. 3 attached images |
| Server code | serverless functions in JavaScript in functions/ — not PHP/Node.js, no npm |
| Build step / npm | None — use CDNs for libraries |
| Visitor accounts | Not yet — visitors are anonymous |
| Database operations | list · view · create · update · delete |
| Database column types | text · number · yes/no · date · relation · image |
| Responsive | responsive by default · can be locked to mobile/desktop only |
| SEO & share previews | must be requested — the AI doesn't add them automatically |
| Images/media | image uploads · the AI can't create images · video through YouTube |
✅ Do
- State the site's goal & users
- Detail it section by section
- Name the data that needs saving
- One big change per prompt
- Use Plan mode for half-formed ideas
- Name specific colors & fonts
🚫 Avoid
- Ultra-short prompts: “make a website”
- Mixing 5 different changes into one prompt
- Asking for PHP / Node.js / npm (use serverless functions)
- Writing API keys in page files
- Saving important data in
localStorage - Assuming visitors have accounts
- Switching styles without saying which part
★Universal Prompt Template
Copy it, fill in the parts inside [ ], then send.