CAKE20

AI Web PaaS

Style and UI

Develop quickly with Cake20 UI and Tailwind CSS already installed in Cake20.

Cake20 UI

  • Cake20 UI and Tailwind CSS are already installed and configured in Cake20. It is used as a basic function without any separate installation or initial setup.
  • Before implementing screens yourself or adding a UI package, use the First find the components and combine them. Form, Table, Modal, Slideover, NavigationMenu and Page series can also be used immediately.
  • AI also considers all Cake20 UI components as already provided features and provides advanced UI. When requested, we implement it quickly by prioritizing existing component combinations.
  • The Lucide icon is also installed by default. Such as Icon name or Button Use it directly in the i-lucide-user format in the icon prop of the component.
  • The Icon component is written without the U prefix, but with i-lucide- in the icon name. The prefix is ​​preserved. Other Iconify collections only require dependencies when needed. Add.
  • Use Cake20 UI components with PascalCase tags without U prefix, such as Card, Button, and Input.
  • Button is a Cake20 UI component and button is a basic HTML element and is case sensitive.
  • UButton and UCard in the Cake20 UI official example were changed to Button and Card in Cake20. Write it. The U prefix grammar is supported for compatibility purposes only.
  • Create custom components so that they do not overlap with Cake20 UI reserved names, such as MyButton.
export const data = { name: "" };

export const save = () => console.log(data.name);

export default () => (
  <Card>
    <Input bind={data.name} placeholder="name" />
    <Button class="mt-3" onClick={save}>save</Button>
  </Card>
);

Cake20 CDN Fonts

Cake20 websites use web fonts by linking versioned CSS from the Cake20 CDN instead of installing the Cake20 Fonts module. Font files are served by the Cake20 CDN, so the browser does not contact an external provider such as Google Fonts.

Place external @import rules before every other rule in app/assets/style.css. Cake20 moves them to stylesheet links in the document head so Preview and production use the same paths.

  • Use Noto Sans KR for Korean and English body copy and Noto Serif KR for headings and quotations.
  • Use Lilex for code and numbers. IBM Plex Sans is also available at /fonts/v1/ibm-plex-sans.css.
  • Select the registered fonts per element with Tailwind's font-sans, font-serif, and font-mono classes.
  • Font CSS and WOFF2 files stay on a versioned path. Change v1 in the CDN path only when intentionally adopting a new version.
  • The CDN catalog links to the copyright notice and full SIL OFL 1.1 text for every font.
  • For a font not provided by the CDN, place WOFF2 files in public/fonts and connect them with @font-face. The website owner must verify its web distribution license.
@import url("https://cdn.cake20.com/fonts/v1/noto-sans-kr.css");
@import url("https://cdn.cake20.com/fonts/v1/noto-serif-kr.css");
@import url("https://cdn.cake20.com/fonts/v1/lilex.css");

@theme {
  --font-sans: "Noto Sans KR Variable", sans-serif;
  --font-serif: "Noto Serif KR Variable", serif;
  --font-mono: "Lilex Variable", monospace;
}

body {
  font-family: var(--font-sans);
}

This differs from the Cake20 Fonts module, where a font-family declaration can trigger font generation. Cake20 explicitly links the CDN stylesheet for each font it uses.

Drag sort DragList

  • DragList is a drag sorting component included in Cake20. It can be used without separate installation or import.
  • Items can be moved between lists that specify the same group, making it suitable for Kanban, order editing, and galleries.
  • The item being dragged and the place where it will be placed are displayed in a basic style, and movement of surrounding items and touch input are also supported.
  • As the dragging item gets closer, surrounding items are pushed out first to make room for it, and you can check the direction of movement even before releasing it.
  • Items grabbed by the mouse immediately follow the cursor with no movement threshold, and only touch input uses anti-flip delays.
  • animation is the movement time, default is 380ms. You can control the movement of the final digit movement with easing.
  • swapThreshold and invertedSwapThreshold adjust the swap response range from 0 to 1, with a default value of 1.
  • If handle is omitted, the entire item is grabbed and moved. The default value for fallbackTolerance is 0, which means it immediately follows mouse movement.
  • Give each item a stable key and save the changed order with onEnd.
  • If handle is specified, the drag will start only from the specified handle, not the entire card.
export const data = {
  cards: [
    { id: 1, title: "design" },
    { id: 2, title: "review" },
  ],
};

export const saveOrder = () => console.log(data.cards);

export default () => (
  <DragList bind={data.cards} group="tasks" handle=".drag-handle" onEnd={saveOrder}>
    {data.cards.map((card) => (
      <article key={card.id}>
        <button class="drag-handle">move</button>
        {card.title}
      </article>
    ))}
  </DragList>
);

Website settings

  • Write package.json as a valid JSON object. It is the single source of Cake20 settings and dependencies.
  • Public settings written in package.json are available on the client and server without a separate import. Approach it like project.title and project.pageSize. Based on actual properties Autocomplete and type generation.
  • The browser's project is a Cake20 View responsive object. Like project.pageSize = 10 If you change the property or nested value directly, the screen that uses it and document.title will change. It will be updated immediately. Because destructured raw values ​​lose responsive connectivity, Access directly through project properties.
  • The project value changed in the browser is only maintained in the current page memory. It is not saved in package.json. To keep a default after refresh, edit and save package.json. Because the project on the server is the startup setting, Use for read only.
  • The notice screen and API of the basic template use pageSize together. If you change the value The number of notices per page applies equally to both sides.
  • The project value is a public setting that is also included in the browser. Password and API key Instead of writing it out, save it to the encryption Secret in your website settings.
  • mode is auto, static, or fullstack. Missing and empty values mean auto. Explicitly use static when the website has no own API, file storage, task, queue, WebSocket, SSE, database, or other executable server source.
  • When AI creates or modifies a website, it must set mode to static after confirming that no server feature is used. Change it to fullstack when adding a server feature. Static mode runs without a website server process.
  • Set data to auto, local, or server in package.json. When omitted, the internal project.data default is auto.
  • auto resolves to server on Cake20 and local in the local CLI. An explicit local or server value always takes precedence over the execution environment.
  • Cake20 keeps name, private, type, and packageManager in package.json. data is stored in the same file, and empty dependencies may be omitted.
  • Legacy project.ts, website.ts, config.ts, and package.ts settings are merged into package.json and removed only after the new file is saved successfully.
  • timezone is optional and uses the IANA time zone, such as Asia/Seoul. Once set up, it will run a website including a Node process and a PostgreSQL connection; Commonly applies to databases, scheduled tasks, and logs. Even if omitted Applies the system local time zone to both sides equally.
  • Device is the main target screen and uses one of desktop, tablet, and mobile. If omitted, it is desktop. The editor's resolution menu and distributed templates Preview will select this device first.
  • orientation is landscape or portrait. If omitted, desktop is Landscape, tablet and mobile use portrait.
  • title is a required string of 1 to 200 characters. Browser tab, HTML title, Used for Open Graph and X Card titles.
  • description is an optional string of 1 to 500 characters. Summary of search results This is the global default value used for link share descriptions.
  • image is an optional string of 1 to 2,000 characters. starting with / Enter a public path or http(s) URL.
  • lang is the language of the HTML document, entered in the format ko or ko-KR.
  • The favicon is the browser icon and is entered as a public path or http(s) URL starting with /.
  • If you leave public/social.jpg and specify image as /social.jpg, Used as a representative image of Open Graph and X Card.
  • social.jpg is not provided by default. link share image Add your own images that best represent your site when needed.
  • If there is an image, X Card is summary_large_image, if not, Created as summary. Featured images are not an essential SEO element.
  • Multi-page search optimization requires a unique title and description for each page.
  • The new website uses Cake20 as its default title.
  • robots.txt and sitemap.xml are managed separately in public, not package.json.
  • app/index.html is visible but kept as a fixed standard file.
// package.json
{
  "title": "Our local cake shop",
  "description": "Introducing the cake we bake ourselves every morning.",
  "mode": "static",
  "data": "auto",
  "timezone": "Asia/Seoul",
  "device": "mobile",
  "orientation": "portrait",
  "image": "/social.jpg",
  "lang": "en",
  "favicon": "/favicon.svg",
  "pageSize": 5
}

// public/social.jpg → /social.jpg

Global CSS

The entire website style is written in app/assets/style.css. Images and fonts in assets are built by Vite when imported from Cake20 View or CSS, and public files can be directly referenced through the / path.

It is recommended to use Tailwind's basic utility first, and bundle repeated styles with Cake20 View components.

Long Tailwind class summary

A long class used only within one Cake20 View component can move to a short string or array variable and connect through class. Combinations Combinations that are repeated on the screen or have a clear design role, such as hero-fade, are Declare it as @utility in app/assets/style.css.

  • Cake20 Runtime loads Tailwind CSS first, so in style.css @import "tailwindcss" will not rebuild or install the package.
  • Short combinations used once stay in JSX. When a class becomes hard to read, Only name variables or @utilities when it is difficult or the same combination is repeated.
  • The class name is a complete string so Tailwind can find it when building. Write it. Use a map of completed strings instead of dynamic combinations like bg-${color}-500.
  • @utility is declared at the top of app/assets/style.css, and Tailwind default Utility combinations are reused with @apply.
// app/pages/index.tsx
const fade = [
  "absolute inset-0 bg-gradient-to-b",
  "from-orange-200/70 via-amber-100/40 to-transparent"
];

export default () => (
  <>
    <div class={fade} />
    <div class="hero-fade" />
  </>
);

/* app/assets/style.css */
@utility hero-fade {
  @apply absolute inset-0 bg-gradient-to-b from-orange-200/70
    via-amber-100/40 to-transparent;
}