Appearance
Lesson 1 — SAP Fiori and your first SAPUI5 app
Review the companion · Assignment
Build a small application with a Say Hello button. By the end, you will be able to explain where the interface is defined, where its behavior lives, and how to run it locally.
1. Start here
Environment: VS Code on your computer. SAP backend/account: not required. Internet access is needed for npm packages, extensions and SAPUI5 resources; local development does not mean fully offline.
You need VS Code, Node.js 24.x LTS with npm, Git, and a current Chrome or Edge browser. Install SAP Fiori tools during this lesson. You should already recognize JavaScript variables, functions and objects; the later lessons add short explanations of the array methods they use.
The checkpoints were generated with SAP Fiori generator 1.34.0 and use SAPUI5 1.148.12, the sap_horizon theme, and a committed npm lockfile. The validation environment uses Node.js 24.22.1 and npm 11.9.0. You do not need those exact patch versions of Node/npm; stay on Node 24.x for these checkpoints. VS Code extension releases can change the wizard labels.
2. Understand the idea
| Term | Meaning | Your role |
|---|---|---|
| SAP Fiori | SAP's user experience approach and design system | Build understandable, consistent and accessible business interfaces. |
| SAPUI5 | The JavaScript UI framework | Compose controls and implement behavior. |
| SAP Fiori elements | A metadata-driven framework built on SAPUI5 | Configure standard application patterns using services, annotations and app configuration. |
A typical service-backed app runs in a browser and calls a backend over HTTP/OData. The backend applies business rules and stores data. This app has no business-data service. Lessons 4–5 use local JSON and browser memory; later lessons introduce OData V4.
A View describes the screen. A Controller handles its interactions. UI5 renders the controls as browser HTML. You work with UI5 controls and their APIs rather than editing their generated DOM.
3. Build it
A. Verify your tools
Open Terminal → New Terminal in VS Code and run:
bash
node --version
npm --version
git --versionCheck: all three commands print a version, and Node prints v24.... If a command is missing, install that tool and reopen VS Code before continuing.
Open Extensions, search for SAP Fiori tools — Extension Pack, verify that the publisher is SAP, and install it. Reload VS Code if requested. Open the Command Palette with Ctrl+Shift+P on Windows/Linux or Cmd+Shift+P on macOS. Search for Fiori: Open Application Generator. Its presence confirms that the extension is available. The first launch may download generator packages.
B. Generate the project
Run Fiori: Open Application Generator and choose the Basic freestyle template (some versions show the application type separately). Enter these values:
| Setting | Value |
|---|---|
| Template | Basic freestyle / SAPUI5 application |
| Data source | None |
| View name | Main |
| Module name | day1 |
| Application namespace | training.fiori |
| Application title | My First Fiori App |
| Description | SAPUI5 guided lessons |
| Minimum SAPUI5 version | 1.148.12, where available |
| TypeScript | No |
| Deployment configuration | No |
| FLP configuration | No |
| Advanced options | Use defaults; select sap_horizon if a theme choice appears |
Open the resulting day1 folder. In webapp/manifest.json, verify that sap.app.id is training.fiori.day1. In webapp/view/Main.view.xml, the controller name must be training.fiori.day1.controller.Main. The namespace entered in the wizard is only the prefix; the module name completes the application ID.
If these checks do not match, generate a new project in a separate parent folder using the values above, then verify it before continuing. Keep any existing work in its original folder. If generation fails, check the extension installation and the error shown in VS Code's Output panel.
C. Use the reproducible preview configuration
Configure the generated project using the files below. Keep the generated Component.js, webapp/model/models.js, App View, App Controller and default routing configuration. They provide the application shell used throughout these lessons.
1. Replace package.json. This defines the local preview and build commands, using the tooling versions recorded in the completed checkpoints.
json
{
"name": "day1",
"version": "0.0.1",
"private": true,
"description": "SAPUI5 guided lessons",
"scripts": {
"start": "fiori run --open \"/index.html\"",
"build": "ui5 build --config=ui5.yaml --clean-dest --dest dist"
},
"devDependencies": {
"@ui5/cli": "4.0.73",
"@sap/ux-ui5-tooling": "1.34.0"
},
"engines": {
"node": ">=24 <25"
}
}2. Replace ui5.yaml. The proxy loads SAPUI5 1.148.12; app reload refreshes the preview when you save.
yaml
specVersion: "4.0"
metadata:
name: training.fiori.day1
type: application
server:
customMiddleware:
- name: fiori-tools-proxy
afterMiddleware: compression
configuration:
ignoreCertErrors: false
ui5:
path:
- /resources
- /test-resources
url: https://ui5.sap.com
version: 1.148.12
- name: fiori-tools-appreload
afterMiddleware: compression
configuration:
port: 35729
path: webapp
delay: 300
builder:
resources:
excludes:
- /test/**
- /localService/**3. Create or replace webapp/index.html. This is the standalone entry page opened by npm start.
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My First Fiori App</title>
<link rel="stylesheet" href="css/style.css">
<script
id="sap-ui-bootstrap"
src="resources/sap-ui-core.js"
data-sap-ui-theme="sap_horizon"
data-sap-ui-resource-roots='{"training.fiori.day1": "./"}'
data-sap-ui-on-init="module:sap/ui/core/ComponentSupport"
data-sap-ui-compat-version="edge"
data-sap-ui-async="true"
data-sap-ui-frame-options="trusted"
></script>
</head>
<body class="sapUiBody sapUiSizeCompact" id="content">
<div
data-sap-ui-component
data-name="training.fiori.day1"
data-id="container"
data-settings='{"id": "training.fiori.day1"}'
data-handle-validation="true"
></div>
</body>
</html>4. Create or replace webapp/css/style.css. Create the css folder if needed. This lets the app fill the browser height.
css
html, body, body > div, #container, #container-uiarea {
height: 100%;
}5. Adjust webapp/manifest.json. Keep the generated file and edit the properties below inside their existing sections. These are property values, not replacements for the entire manifest.
In sap.app, keep id as training.fiori.day1, title as and description as . Replace its i18n value with:
json
{
"bundleUrl": "i18n/i18n.properties",
"supportedLocales": [""],
"fallbackLocale": ""
}In sap.ui5.dependencies, set minUI5Version to 1.148.12 and ensure libs contains "sap.m": {} and "sap.ui.core": {}. Keep any other generated library entries. In sap.ui5.models, replace the i18n value with:
json
{
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "training.fiori.day1.i18n.i18n",
"supportedLocales": [""],
"fallbackLocale": ""
}
}The empty locale uses the default text file without requesting translated bundles. Keep sap.ui5.rootView and sap.ui5.routing as generated: the App View contains the app control and the default route targets Main.
6. Check webapp/i18n/i18n.properties. Ensure these entries exist, replacing their values if needed:
properties
appTitle=My First Fiori App
appDescription=SAPUI5 guided lessons
title=My First Fiori AppOpen a terminal in the project root, the folder containing package.json, and install the configured dependencies:
bash
npm install
npm startnpm install creates or updates package-lock.json to match your edited package file. Keep that lockfile with your project; use npm ci for subsequent clean installs and when copying the project. The completed downloads have their own lockfiles, so a newly generated project's transitive dependency versions may differ.
npm start starts a local development server and opens /index.html; it does not deploy to SAP. If the browser does not open, use the localhost URL printed in the terminal and append /index.html. Leave this terminal running. Stop it later with Ctrl+C. Record these run commands and the Node.js prerequisite in your project's README.md.
Check: an application page opens. It can be mostly empty before you add your controls. A failed JSON/business-service request is not expected because no business service is configured.
D. Replace the Main View
Open webapp/view/Main.view.xml. Replace its entire contents with the following file. Leave App.view.xml unchanged: that is the generated outer application shell.
webapp/view/Main.view.xml — complete file
xml
<mvc:View
controllerName="training.fiori.day1.controller.Main"
displayBlock="true"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m">
<Page id="mainPage" title="My First Fiori App">
<content>
<VBox id="contentBox" class="sapUiSmallMargin">
<Title id="welcomeTitle" text="Welcome to SAPUI5" />
<Text id="welcomeText" text="This is my first SAPUI5 application." />
<Button id="sayHelloButton" text="Say Hello" press=".onSayHello" class="sapUiSmallMarginTop" />
</VBox>
</content>
</Page>
</mvc:View>Page, VBox, Title, Text and Button are SAPUI5 controls. The sap.m default XML namespace tells UI5 which library contains them. The mvc prefix identifies the View class.
The IDs describe purpose: mainPage, welcomeTitle, sayHelloButton. The generated shell already assigns stable IDs to its views. UI5 prefixes local control IDs with the view's identity, so the same local name can safely appear in another view.
E. Replace the Main Controller
Open webapp/controller/Main.controller.js and replace the entire file:
webapp/controller/Main.controller.js — complete file
javascript
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageToast"
], function (Controller, MessageToast) {
"use strict";
return Controller.extend("training.fiori.day1.controller.Main", {
onSayHello: function () {
MessageToast.show("Hello from SAPUI5!");
}
});
});The dependency list imports Controller and MessageToast in the same order as the function parameters. press=".onSayHello" resolves the handler on this View's controller. The leading dot is intentional. MessageToast.show(...) displays temporary feedback.
Changed files: the configuration and text files in step C, the npm-generated package-lock.json, your project README.md, webapp/view/Main.view.xml and webapp/controller/Main.controller.js.
4. Verify your result
Save both files. Refresh the browser if the preview does not reload automatically.
- Confirm the page title, welcome title, text and button are visible.
- Select Say Hello. You should see Hello from SAPUI5!.
- Open browser DevTools → Console. Investigate application errors before continuing.
- Change the welcome text and the toast message. Predict which file controls each change, then verify your prediction.
- Use Tab to focus the button and Enter or Space to activate it.
Expected screen: My First Fiori App, a Welcome to SAPUI5 heading, an explanatory sentence and a Say Hello button.
Completed Lesson 1 checkpoint. Compare it with your work if needed. Keep your working folder for Lesson 2.
5. Troubleshoot
| Symptom | Likely cause | What to do |
|---|---|---|
node/npm not recognized | Tool installation/PATH is incomplete | Install Node 24 LTS, then reopen VS Code and check versions again. |
| Fiori command missing | Extension disabled or not installed | Check the SAP extension pack, enable it and reload VS Code. |
npm ci fails | Wrong folder or mismatched package/lockfile | Confirm package.json is in the current folder. After editing it in step C, run npm install to update the lockfile; use npm ci once the two files agree. |
| Preview port is busy | Another development server is running | Stop the old server with Ctrl+C, or run npm start -- --port 8081. |
| Controller cannot load | Namespace, case or filename mismatch | Compare the app ID, controllerName and Controller.extend with the exact values above. |
| Button does nothing | Handler or import mismatch | Check .onSayHello, onSayHello and the MessageToast dependency/parameter order. |
| Resources fail to load | Network/proxy problem | Check DevTools → Network; SAPUI5 and npm downloads need internet access. |
6. Check your understanding
Try answering before opening the answers.
- How do SAP Fiori, SAPUI5 and SAP Fiori elements differ?
- What does
npm startdo? - How does the button find its handler?
- Why use semantic control IDs?
Suggested answers
- Fiori is the UX/design approach; SAPUI5 is the UI framework; Fiori elements adds metadata-driven application patterns on SAPUI5.
- It runs the configured development server. It does not publish the app or create a business backend.
- The XML
pressevent attribute points to.onSayHello; UI5 calls that method on the View's controller. - Meaningful IDs support reliable lookup, tests and adaptation and remain understandable as layouts change.
7. Continue to Lesson 2
Keep this same project and application ID. Lesson 2 explains the generated files and extracts the greeting into a reusable module. Open Lesson 2.
8. Official references
Use the SAPUI5 version selector to read the API for 1.148.12, the version used by these checkpoints. Documentation checked on 15 November 2026.