cap-sveltekit-sample Svelte Themes

Cap Sveltekit Sample

CAP + SvelteKit: Using CAP's programmatic service APIs in frontend code

CAP + SvelteKit: Using CAP's programmatic service APIs in frontend code

This repository contains an SAP CAP application with a SvelteKit frontend that runs server-side inside the CAP server. This lets the frontend call CAP services directly via cds.ql and the programmatic service APIs instead of going through OData or REST.

The idea

SvelteKit is a full-stack web framework, comparable to Next.js for React. It supports server-side rendering (SSR), meaning each page can have a server-side load function (+page.server.ts) that fetches data before the HTML is rendered. The browser receives a fully rendered page.

In this demo, SvelteKit runs inside the CAP server process. The server-side load functions therefore have direct access to CAP's programmatic APIs. Instead of calling an OData or REST endpoint, the frontend code uses cds.connect.to() and cds.ql (SELECT, INSERT, etc.) to query a CAP service directly. For example:

// app/sample/src/routes/po-tracker/+page.server.ts
import cds from "@sap/cds";
import PurchaseOrderService, { PurchaseOrders } from "#cds-models/PurchaseOrderService";

export const load: PageServerLoad = async () => {
  const srv = await cds.connect.to(PurchaseOrderService);

  const [totalCount, pendingCount, recentOrders] = await srv.run([
    SELECT.one.from(PurchaseOrders).columns("count(*) as value"),
    SELECT.one.from(PurchaseOrders).columns("count(*) as value").where({ status: "Pending" }),
    SELECT.from(PurchaseOrders).orderBy("createdAt desc").limit(5),
  ]);

  return { totalCount: totalCount.value, pendingCount: pendingCount.value, recentOrders };
};

The call still goes through the CAP service layer, so authorization, validations, and custom handlers behave as they normally would. The only difference is that it runs in-process via CAP's service API instead of being sent over HTTP/OData.

Because the data is fetched on the server, the browser receives fully rendered HTML with the data already included on first load.

Benefits of this approach

  • The frontend consumes CAP services via the programmatic cds.ql and service API (cds.connect.to, SELECT.from, etc.) instead of OData or REST. All service handlers, validations, and authorization still apply.
  • Pages arrive fully rendered from the server. The browser shows content immediately without waiting for client-side API calls, which works well for dashboards and data-heavy views.
  • Frontend and backend are packaged into one MTA module, so there is no need for separate static file hosting.
  • cds-typer generates TypeScript models from the CDS schema. These are imported in the server-side load functions, so queries are typed at compile time.

Project structure

srv/
  server.ts              # CAP server, mounts SvelteKit as middleware
  purchase-order-service.ts/cds  # Sample service definition + custom handlers
db/
  schema.cds             # Domain model
app/sample/
  src/routes/
    +page.svelte         # Start page with app selection
    po-tracker/          # UI5 Web Components frontend
    ssr-dashboard/       # Skeleton UI + Tailwind CSS frontend

Both routes show the same purchase order data (KPIs, charts, order list) and use the same CDS queries in their server-side load functions. They differ in how well they benefit from SSR:

  • po-tracker uses SAP UI5 Web Components. Because UI5 Web Components rely on the Shadow DOM, they can only render in the browser. The server still fetches the data and delivers it with the initial HTML, but the UI5 components themselves are hydrated on the client side.
  • ssr-dashboard uses Skeleton UI with Tailwind CSS. These are plain HTML elements styled with CSS utility classes, so the entire page — including all visual components — can be fully rendered on the server. This is the more effective use of SSR and shows what a completely server-rendered CAP frontend can look like.

Prerequisites

  • SAP CDS DK >= 9 (npm i -g @sap/cds-dk)
  • For SAP BTP deployment: Cloud Foundry CLI, MBT (npm i -g mbt)

Local setup

Build & Deploy to BTP Trial

  • Create a BTP trial account: Open https://account.hanatrial.ondemand.com/trial/#/home/trial and follow the instructions there.
  • Build the app
    npm run build
    
  • Log in to Cloud Foundry in your trial subaccount
    cf login -a https://api.cf.<region>.hana.ondemand.com
    
  • Deploy the app
    npm run deploy
    
  • Access the app via the approuter URL.

How SvelteKit is integrated into CAP

  • Development: Vite (SvelteKit’s dev server and build tool) is registered as Express middleware for the /app/sample path. When a request starts with /app/sample, it is forwarded to Vite. Vite then serves the SvelteKit pages, handles hot module replacement, and compiles the code on the fly. Other routes, such as /odata/..., are still handled directly by CAP as usual.

  • Production: vite build together with the SvelteKit Node adapter produces a Node.js request handler (handler.js). At startup, the CAP server imports this handler and mounts it for all non-OData/REST routes. In other words, CAP keeps handling /odata/..., while everything under /app/sample (and other UI routes) is rendered by SvelteKit inside the same Node.js process.

Top categories

Loading Svelte Themes