# Hello World example using a function page

> Build your first function page by returning an SDUI spec from a Rippling function.

Build your first function page by returning an SDUI spec from a Rippling function.

## Overview

This guide walks you through the minimum code needed to render a **function page**: a Rippling function that returns an **SDUI spec**, which App Studio renders as a native page.

You will:

1.  Write a function that handles the `init` action and returns an SDUI spec.
2.  Attach that function to a function page in App Studio.

The example below is intentionally small—a heading and a line of text—so you can focus on the function-page pattern before adding state, bindings, or server round-trips.

* * *

## How this guide fits in

| Doc | Use it for |
| --- | --- |
| [Get started](https://developer.rippling.com/documentation/rippling-platform/sdui/getting-started) | How function pages load and when the server runs |
| **Hello World** (this page) | First `onRipplingEvent` handler and SDUI spec |
| [Server round-trips](https://developer.rippling.com/documentation/rippling-platform/sdui/server-round-trips) | `triggerFunction` and follow-up handler actions |
| [State & Data Binding](https://developer.rippling.com/documentation/rippling-platform/sdui/state-data-binding) | `$state`, `$bindState`, lists, and local actions |
| [Components](https://developer.rippling.com/documentation/rippling-platform/sdui/components) | Props, events, and catalog lookup |
| [Reference](https://developer.rippling.com/documentation/rippling-platform/sdui/reference) | Spec shape, imports, and actions table |

* * *

## Before you start

Create a function in **Developer > Functions**. See [Get started with Functions](https://developer.rippling.com/documentation/rippling-platform/developer/functions/getting-started) if you need the setup steps.

Your function exports `onRipplingEvent`. Rippling calls it with an `action` parameter. For a new function page, the important case is:

| Situation | `action` value | What to return |
| --- | --- | --- |
| User opens the page | `init` | An SDUI spec (JSON) inside the response body |

* * *

## Step 1: Build the SDUI spec

Import catalog builders and `render` from the custom-apps catalog. Compose a component tree and pass it to `render`:

```typescript
import {
  Heading,
  Text,
  VStack,
  render,
} from '@rippling/pebble-sdui-web/catalogs/custom-apps';

function buildSpec() {
  const root = VStack({
    props: { gap: 'space300' },
    children: [
      Heading({
        props: {
          level: 2,
          text: 'Hello, world',
        },
      }),
      Text({
        props: {
          text: 'This function page was built with an SDUI spec.',
          typestyle: 'typestyleBodyMedium',
        },
      }),
    ],
  });

  return render({ root, state: {} });
}
```

`render()` flattens the component tree into the JSON shape Rippling's renderer expects. This page has no interactive state yet, so `state` is an empty object.

* * *

## Step 2: Return the spec on `init`

Wire the spec into `onRipplingEvent` and return it when the page loads:

```typescript
import { FunctionEvent, FunctionResponse } from '@rippling/rippling-sdk';

export async function onRipplingEvent(
  event: FunctionEvent,
): Promise<FunctionResponse> {
  const params = (event.parameters ?? {}) as Record<string, string | undefined>;
  const action = params.action;

  if (action === 'init') {
    const spec = buildSpec();

    return new FunctionResponse({
      body: { spec: JSON.stringify(spec) },
      statusCode: 200,
      headers: {},
      message: '',
    });
  }

  return new FunctionResponse({
    body: {},
    statusCode: 400,
    headers: {},
    message: 'Unknown action',
  });
}
```

On `init`, the response body must include `spec` as a JSON string. Rippling parses it and renders the function page.

* * *

## Step 3: Attach the function in App Studio

1.  Open **Custom Apps** and create or edit an app (see [Get started with custom apps](https://developer.rippling.com/documentation/rippling-platform/custom-apps/get-started)).
2.  Add a page and choose **Function page**.
3.  Select your function in **Search functions**.

Open the app to see the rendered function page.

* * *

## Complete example

```typescript
import {
  Heading,
  Text,
  VStack,
  render,
} from '@rippling/pebble-sdui-web/catalogs/custom-apps';
import { FunctionEvent, FunctionResponse } from '@rippling/rippling-sdk';

function buildSpec() {
  const root = VStack({
    props: { gap: 'space300' },
    children: [
      Heading({
        props: {
          level: 2,
          text: 'Hello, world',
        },
      }),
      Text({
        props: {
          text: 'This function page was built with an SDUI spec.',
          typestyle: 'typestyleBodyMedium',
        },
      }),
    ],
  });

  return render({ root, state: {} });
}

export async function onRipplingEvent(
  event: FunctionEvent,
): Promise<FunctionResponse> {
  const params = (event.parameters ?? {}) as Record<string, string | undefined>;
  const action = params.action;

  if (action === 'init') {
    return new FunctionResponse({
      body: { spec: JSON.stringify(buildSpec()) },
      statusCode: 200,
      headers: {},
      message: '',
    });
  }

  return new FunctionResponse({
    body: {},
    statusCode: 400,
    headers: {},
    message: 'Unknown action',
  });
}
```

* * *

## Next steps

-   Call your function from the page with [Server round-trips](https://developer.rippling.com/documentation/rippling-platform/sdui/server-round-trips).
-   Add reactive text and inputs with [State & Data Binding](https://developer.rippling.com/documentation/rippling-platform/sdui/state-data-binding).
-   Look up component props and events in the [component catalog](https://developer.rippling.com/documentation/rippling-platform/sdui/components).
-   See the full spec shape (`props`, `on`, `visible`, `repeat`, `children`) in [Reference](https://developer.rippling.com/documentation/rippling-platform/sdui/reference#component-configuration).

Source: https://developer.rippling.com/documentation/rippling-platform/sdui/hello-world

> For the complete documentation index, see [llms.txt](https://developer.rippling.com/llms.txt). Public pages have a Markdown version at the same URL with .md added.
