Skip to content

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 ​

TermMeaningYour role
SAP FioriSAP's user experience approach and design systemBuild understandable, consistent and accessible business interfaces.
SAPUI5The JavaScript UI frameworkCompose controls and implement behavior.
SAP Fiori elementsA metadata-driven framework built on SAPUI5Configure 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 --version

Check: 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:

SettingValue
TemplateBasic freestyle / SAPUI5 application
Data sourceNone
View nameMain
Module nameday1
Application namespacetraining.fiori
Application titleMy First Fiori App
DescriptionSAPUI5 guided lessons
Minimum SAPUI5 version1.148.12, where available
TypeScriptNo
Deployment configurationNo
FLP configurationNo
Advanced optionsUse 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 App

Open a terminal in the project root, the folder containing package.json, and install the configured dependencies:

bash
npm install
npm start

npm 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.

  1. Confirm the page title, welcome title, text and button are visible.
  2. Select Say Hello. You should see Hello from SAPUI5!.
  3. Open browser DevTools → Console. Investigate application errors before continuing.
  4. Change the welcome text and the toast message. Predict which file controls each change, then verify your prediction.
  5. 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 ​

SymptomLikely causeWhat to do
node/npm not recognizedTool installation/PATH is incompleteInstall Node 24 LTS, then reopen VS Code and check versions again.
Fiori command missingExtension disabled or not installedCheck the SAP extension pack, enable it and reload VS Code.
npm ci failsWrong folder or mismatched package/lockfileConfirm 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 busyAnother development server is runningStop the old server with Ctrl+C, or run npm start -- --port 8081.
Controller cannot loadNamespace, case or filename mismatchCompare the app ID, controllerName and Controller.extend with the exact values above.
Button does nothingHandler or import mismatchCheck .onSayHello, onSayHello and the MessageToast dependency/parameter order.
Resources fail to loadNetwork/proxy problemCheck DevTools → Network; SAPUI5 and npm downloads need internet access.

6. Check your understanding ​

Try answering before opening the answers.

  1. How do SAP Fiori, SAPUI5 and SAP Fiori elements differ?
  2. What does npm start do?
  3. How does the button find its handler?
  4. Why use semantic control IDs?
Suggested answers
  1. Fiori is the UX/design approach; SAPUI5 is the UI framework; Fiori elements adds metadata-driven application patterns on SAPUI5.
  2. It runs the configured development server. It does not publish the app or create a business backend.
  3. The XML press event attribute points to .onSayHello; UI5 calls that method on the View's controller.
  4. 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.

Independent learning materials for SAP frontend development.